社区讨论
求思路证明或证伪
P11361[NOIP2024] 编辑字符串参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @m4cjn6b0
- 此快照首次捕获于
- 2024/12/06 17:28 去年
- 此快照最后确认于
- 2025/11/04 13:17 4 个月前
我的思路是以0为分界分别处理出每个连续1区间内的1和0的个数然后进行贪心,考场最后一个样例没过,官方数据65pts
CPP#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int t,n;
char s1[N],s2[N],t1[N],t2[N];
struct node{
int x,y,s1,s0;
}f1[N],f2[N];
int ans;
void init(char s[],char t[],node f[],int &num){//统计
int lst=1;
for(int i=1;i<=n;i++){
if(t[i]=='0'){
f[num].x=f[num].y=i;
lst=i+1;
if(s[i]=='0')
f[num].s0++;
else
f[num].s1++;
num++;
continue;
}
if(s[i]=='0')
f[num].s0++;
else
f[num].s1++;
if(i==n){
f[num].x=lst;
f[num].y=i;
break;
}
if(t[i+1]=='0'){
f[num].x=lst;
f[num].y=i;
num++;
}
}
}
int main(){
// freopen("edit.in","r",stdin);
// freopen("edit.out","w",stdout);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
memset(t2,0,sizeof(t1));
memset(t2,0,sizeof(t2));
cin>>s1+1>>s2+1>>t1+1>>t2+1;
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
int num1=1,num2=1;
ans=0;
init(s1,t1,f1,num1);
init(s2,t2,f2,num2);
// for(int i=1;i<=num1;i++)
// printf("%d %d %d %d\n",f1[i].x,f1[i].y,f1[i].s0,f1[i].s1);
// puts("");
// for(int i=1;i<=num2;i++)
// printf("%d %d %d %d\n",f2[i].x,f2[i].y,f2[i].s0,f2[i].s1);
int i=1,j=1;
//神秘的贪心
while(i<=num1||j<=num2){
// printf("%d %d %d\n",i,j,ans);
if(f1[i].y<f2[j].y){
int minn=1e9;
if(f1[i].x<f2[j].x)
minn=f2[j].y-f1[i].x+1;
int min0=min(f1[i].s0,f2[j].s0),min1=min(f1[i].s1,f2[j].s1);
int sum=min(min0+min1,minn);
// cout<<i<<" "<<j<<" "<<minn<<" "<<min0<<" "<<min1<<" "<<sum<<endl;
ans+=min(min0+min1,minn);
if(minn<min0+min1){
if(min1>min0){
f1[i].s1-=min(min1,minn);
f2[j].s1-=min(min1,minn);
f1[i].s0-=minn-min(min1,minn);
f2[j].s0-=minn-min(min1,minn);
i++;
continue;
}
if(min0>=min1){
f1[i].s0-=min(min0,minn);
f2[j].s0-=min(min0,minn);
f1[i].s1-=minn-min(min0,minn);
f2[j].s1-=minn-min(min0,minn);
}
i++;
continue;
}
f1[i].s0-=min0;
f1[i].s1-=min1;
f2[j].s0-=min0;
f2[j].s1-=min1;
i++;
}else if(f1[i].y>f2[j].y){
int minn=1e9;
if(f2[j].x<f1[i].x)
minn=f2[j].y-f1[i].x+1;
int min0=min(f1[i].s0,f2[j].s0),min1=min(f1[i].s1,f2[j].s1);
int sum=min(min0+min1,minn);
// cout<<i<<" "<<j<<" "<<minn<<" "<<min0<<" "<<min1<<" "<<sum<<endl;
ans+=min(min0+min1,minn);
if(minn<min0+min1){
// cout<<1<<endl;
if(min1>min0){
f1[i].s1-=min(min1,minn);
f2[j].s1-=min(min1,minn);
f1[i].s0-=minn-min(min1,minn);
f2[j].s0-=minn-min(min1,minn);
j++;
continue;
}
if(min0>=min1){
f1[i].s0-=min(min0,minn);
f2[j].s0-=min(min0,minn);
f1[i].s1-=minn-min(min0,minn);
f2[j].s1-=minn-min(min0,minn);
}
j++;
continue;
}
f1[i].s0-=min0;
f1[i].s1-=min1;
f2[j].s0-=min0;
f2[j].s1-=min1;
j++;
}else{
int min0=min(f1[i].s0,f2[j].s0),min1=min(f1[i].s1,f2[j].s1);
// cout<<min0<<" "<<min1<<endl;
ans+=min0+min1;
f1[i].s0-=min0;
f1[i].s1-=min1;
f2[j].s0-=min0;
f2[j].s1-=min1;
i++;
j++;
}
// printf("%d %d %d\n",i,f1[i].s0,f1[i].s1);
}
printf("%d\n",ans);
}
return 0;
}
/*
1
10
1010101010
0101010110
1100110011
0010101011
*/
回复
共 4 条回复,欢迎继续交流。
正在加载回复...