LGP7814题解

lmpp 教你对着样例得到做法.jpg

题意:给定一个长度为 $ n $ 的字符串 A,要求你构造一个字符串 B,使得 A 是 B 的子序列且 A 不是 B 的子串。

首先给出无解的判断方法:

if(n==1||n==m||(n==2&&A[1]!=A[2])){
	printf("-1\n");continue;
}

无解的判断方法很好理解吧 qwq。

然后观察样例:

样例:

010->01110
1101->10100101
11111->111101

除了第二个,第一个和第三个是不是都是在 原串中插入一段 \(0\)\(1\) 啊?

思考这样做的正确性。B一定是 A 的子串,但 A 真的不是 B 的子序列吗?

好像如果能够把控中间插入的是 \(0\) 还是 \(1\),那么 A 就不是 B 的子串!

至于这个位置,分两种情况讨论:

  1. A 串存在一个位置 \(i\) 使 \(A_i=A_{i+1}\)

肯定在 \(i\) 的后面插入一串和 \(A_i\) 相反颜色的字符串啊!

  1. 不存在这个位置

那么整个串就是 \(0101010101...\) 或者 \(10101010101...\),在中间随便一个位置插入就行,\(0\)\(1\) 都可以。

不过要注意一下判断当 \(n=3\) 的时候有可能出锅。

#include<cstdio>
const unsigned M=2e6+5;
char A[M];unsigned T,n,m;
signed main(){
	register unsigned i,j;bool f;
	scanf("%u",&T);
	while(T--){
		scanf("%u%u%s",&n,&m,A+1);f=true;
		if(n==1||n==m||(n==2&&A[1]!=A[2])){
			printf("-1\n");continue;
		}
		for(i=1;i<n;++i){
			if(A[i]==A[i+1]){
				for(j=1;j<=i;++j)printf("%c",A[j]);
				for(j=1;j<=m-n;++j)putchar(A[i]=='0'?'1':'0');
				for(j=i+1;j<=n;++j)printf("%c",A[j]);printf("\n");f=false;break;
			}
		}
		if(f){
			if(n==3){
				printf("%c%c",A[1],A[2]);
				for(i=1;i<=m-n;++i)printf("%c",A[2]);printf("%c\n",A[3]);
			}
			else{
				for(i=1;i<=n-2;++i)printf("%c",A[i]);
				for(i=1;i<=m-n;++i)printf("%c",A[n-2]);printf("%c%c\n",A[n-1],A[n]);
			}
		}
	}
}
posted @ 2022-01-10 16:57  Prean  阅读(25)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};