gym-101755 M Forgotten Spell 递归写法,避免复杂分类讨论

【题意】:

链接: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 过这题的人真的太强了。

猜你喜欢

转载自blog.csdn.net/gymgym1212/article/details/81122180