【题意】:
链接:gym101755M -Forgotten Spell
有一个初始的字符串,不知道是什么。给你三个长度相等的字符串,每个字符串最多有一个字符和初始字符串不一样,问你能不能通过这三个字符串求出原来的初始字符串,根据情况输出。
【想法】:
首先我们可以确定一点,如果有超过三列,不是完全相等的,那么肯定输出“Impossible”。
然后我们再思考,有0列和1列,不是完全相等的情况。这个时候,这一列,随便你改成什么字母,都满足条件,所以应该输出“Ambiguous”。
接下来剩下的,只有2列和3列,不是完全相等的情况了。
把这几列找出来,放到一个数组里存下来,同时记得保存这些列所在的位置。
如:
ab
aa
ba
————————————————————————
那么,第一个人最多只要放 25*3个情况,所以用递归去放字母,和原来一样的情况记得不要放,会重复。复杂度最多是 (25*3)^3。
然后用一个tot记录满足情况的答案有多少种。按照情况输出答案即可。
【AC代码】:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char ch[4][200000+10];
int pos[4];
char diff[4][4],ans[4][4],temp[4][4];
int num[200000+10][30];
int cnt,tot;
void dfs(int x)
{
if(x>3){
int flag=0;
for(int i=1;i<=cnt;i++){
if(temp[1][i]==temp[2][i]&&temp[1][i]==temp[3][i]){
}
else{
flag=1;
break;
}
}
if(flag==0){
tot++;
for(int i=1;i<=cnt;i++){
for(int j=1;j<=3;j++){
ans[j][i]=temp[j][i];
}
}
}
return;
}
for(int j=1;j<=cnt;j++){
temp[x][j]=diff[x][j];
}
dfs(x+1);
for(int i=1;i<=cnt;i++){
for(int j=0;j<26;j++){
if(j+'a'!=diff[x][i]){
temp[x][i]=j+'a';
dfs(x+1);
temp[x][i]=diff[x][i];
}
}
}
}
int main()
{
for(int i=1;i<=3;i++){
scanf("%s",ch[i]+1);
//printf("%s\n",ch[i]+1);
}
int n=strlen(ch[1]+1);
cnt=0;tot=0;
for(int i=1;i<=n;i++){
for(int j=2;j<=3;j++){
if(ch[j][i]!=ch[j-1][i]){
cnt++;
if(cnt>3) return 0*printf("Impossible\n");
pos[cnt]=i;
for(int h=1;h<=3;h++){
diff[h][cnt]=ch[h][i];
}
break;
}
}
}
if(cnt==0||cnt==1){
printf("Ambiguous\n");
return 0;
}
dfs(1);
if(tot==0){
printf("Impossible\n");
}
else if(tot>1){
printf("Ambiguous\n");
}
else{
for(int i=1;i<=cnt;i++){
for(int j=1;j<=3;j++){
ch[j][pos[i]]=ans[j][i];
}
}
printf("%s\n",ch[1]+1);
}
return 0;
}
【最后】:
强行if else 过这题的人真的太强了。