Codeforces Round #658 (Div. 2) 参与排名人数14674
[codeforces 1382C2] Prefix Flip (Hard Version) 翻转的利器双指针(构造)
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1382/problem/C2
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
C2 - Prefix Flip (Hard Version) | GNU C++17 | Accepted | 62 ms | 4600 KB |
题目大意:通过操作,将字串a变成字串b.操作规则,必须对字串a从头开始处理,取反,翻转。有操作次数的限制。输出操作次数,及每次操作对应的区间。
基本思路:涉及翻转,需上双指针。需记录取反的次数,需记录翻转的方向。读者若能弄懂下面的样例模拟过程,应该能编写成功。
样例模拟如下:
2
01
10
a b位置1 2
a 元素0 1
b 元素1 0
因a[1]==b[2],需变换a的区间[1,1]
a b位置1 2
a 元素1 1
b 元素1 0
因a[1]!=b[2],需变换a的区间[1,2]
a b位置1 2
a 元素0 0
b 元素1 0
因a[1]!=b[1],需变换a的区间[1,1]
a b位置1 2
a 元素1 0
b 元素1 0
输出:
3 1 2 1
5
01011
11100
a b位置1 2 3 4 5
a 元素0 1 0 1 1
b 元素1 1 1 0 0
因a[1]==b[5],需变换a的区间[1,1]
a b位置1 2 3 4 5
a 元素1 1 0 1 1
b 元素1 1 1 0 0
因a[1]!=b[5],需变换a的区间[1,5].对应原始a的区间[1,5],取反,翻转,用掉原始的a[1],剩下区间[2,5]
a b位置1 2 3 4 5
a 元素0 0 1 0 0
b 元素1 1 1 0 0
因a[1]==b[4],需变换a的区间[1,1]
a b位置1 2 3 4 5
a 元素1 0 1 0 0
b 元素1 1 1 0 0
因a[1]!=b[4],需变换a的区间[1,4].对应原始a的区间[2,5],取反,翻转,用掉原始的a[5],剩下区间[2,4]
a b位置1 2 3 4 5
a 元素1 0 1 0 0
b 元素1 1 1 0 0
因a[1]==b[3],需变换a的区间[1,1]
a b位置1 2 3 4 5
a 元素0 0 1 0 0
b 元素1 1 1 0 0
因a[1]!=b[3],需变换a的区间[1,3].对应原始a的区间[2,4],取反,翻转,用掉原始的a[2],剩下区间[3,4]
a b位置1 2 3 4 5
a 元素0 1 1 0 0
b 元素1 1 1 0 0
因a[1]!=b[2],需变换a的区间[1,2].对应原始a的区间[3,4],取反,翻转,用掉原始的a[4],剩下区间[3,3]
a b位置1 2 3 4 5
a 元素0 1 1 0 0
b 元素1 1 1 0 0
因a[1]!=b[1],需变换a的区间[1,1].对应原始a的区间[3,3],取反,翻转,用掉原始的a[3],没有剩下区间
a b位置1 2 3 4 5
a 元素1 1 1 0 0
b 元素1 1 1 0 0
输出:
8 1 5 1 4 1 3 2 1
AC代码如下:
#include <stdio.h>
#include <string.h>
#define maxn 100010
char a[maxn],b[maxn];
int c[maxn<<1],cn;
int main(){
int t,n,i,l,r,delta,now,change,tmp;//change记录翻转次数
char d;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
scanf("%s",a+1);
scanf("%s",b+1);
l=1,r=n,delta=1,now=n,change=0,cn=0;//delta记录序列的出来方向
while(1){
if(change%2==0)d=a[l];//d对应比较的第一个字母
else d=!(a[l]-'0')+'0';
if(now==1){//特判,最后只剩一个字母
if(d!=b[now])cn++,c[cn]=1;
break;
}
if(d!=b[now])cn++,c[cn]=now,now--,tmp=l,l=r,r=tmp+delta,change++,delta*=-1;//d(变换后a中的首字母),now表示处理到的b的字母所处的位置。
else cn++,c[cn]=1,a[l]=!(a[l]-'0')+'0';//d==b[now];只处理区间[1,1]
}
printf("%d",cn);
for(i=1;i<=cn;i++)printf(" %d",c[i]);
printf("\n");
}
return 0;
}
类似题目:
AtCoder Beginner Contest 158 D String Formation 首尾顺序可变的字符串
来源:oschina
链接:https://my.oschina.net/u/4260177/blog/4429012