无
  • 板块灌水区
  • 楼主lucy2012
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/8/8 15:22
  • 上次更新2024/8/8 16:01:49
查看原帖
无
1252442
lucy2012楼主2024/8/8 15:22

求思路,附加题目题解:

题意简述

选定一段区间 [l,r][l,r],使得区间外的 11 的数量和区间内的 00 的数量的最大值尽可能小。

思路

贪心一下发现,最优的区间两个端点一定是 11,可以反证,以 11 两边的一个或连续一段 00 结尾,显然不如回退到 11 的位置来减少区间内 00 的数量。因此,记录所有 11 的位置下标,用前缀和维护区间 00 和 11 的数量,又因为对于每一个左端点,删掉的 11 非严格递减,区间内 00 非严格递增,用二分求解对于每一个左端点的最优右端点即可。(找到删掉的 11 恰好小于保留的 00 和恰好大于等于的位置,比较那个更优)。

离离原上谱代码:

#include<bits/stdc++.h>
using namespace std;
int n,len,cnt,num,a[2000010],sum[2000010],ans=1e9,l,r;
string s;
int f(int x){//二分这里完全打错了 
	int ll=x,rr=r,mid;
	while(ll<rr){
		mid=(ll+rr)/2;
		if(mid-(sum[mid+1]-sum[x+1])-x<=rr-(sum[rr+1]-sum[x+1])-x){
			rr=mid;
		}else{
			ll=mid+1;
		}
	}
	return min(ll-(sum[ll+1]-sum[x+1])-x,rr-(sum[rr+1]-sum[x+1])-x);
}
int main(){
    cin>>s;
    n=s.length();
    for(int i=0;i<n;i++){
    	sum[i+1]=sum[i]+s[i]-'0';
    	if(s[i]=='1'){
    		a[++cnt]=i;
	    }
	}
	l=a[1],r=a[cnt];
	for(int i=l;i<=r;i++){
		if(f(i)<ans)//这里判断也有问题 
		    ans=f(i);
	}
	cout<<ans;
    return 0;
}
//云若浮沫夕阳下 
2024/8/8 15:22
加载中...