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 的子串!
至于这个位置,分两种情况讨论:
- A 串存在一个位置 \(i\) 使 \(A_i=A_{i+1}\)。
肯定在 \(i\) 的后面插入一串和 \(A_i\) 相反颜色的字符串啊!
- 不存在这个位置
那么整个串就是 \(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]);
}
}
}
}