[codeforces 1382C2] Prefix Flip (Hard Version) 翻转的利器双指针(构造)

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

ProblemLangVerdictTimeMemory
C2 - Prefix Flip (Hard Version) GNU C++17Accepted62 ms4600 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 首尾顺序可变的字符串

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值