洛谷P1092

来源:互联网 发布:数据库触发器 编辑:程序博客网 时间:2024/06/14 04:21

错误的部分

如果您要看标程或者急着去干其它事,请直接往最下面翻

这道题废了我两天
大佬说这道题从后往前搜索,于是我就这样写的

#include<bits/stdc++.h>#define wxh cout<<"mmp"<<endl;#define dxy cout<<x<<" "<<add<<" "<<y<<" "<<z<<" "<<m<<endl;using namespace std;int n,ans[144];char a[27],b[27],c[27];bool use[27];void pr(){    for(int i='A';i<'A'+n;i++){        cout<<ans[i]<<" ";    }    cout<<ans['A'+n-1];    return;}void dfs(int x,int add){    wxh    int y=a[n-x],z=b[n-x],m=c[n-x];    dxy    if(x==n+1){//      wxh        pr();        exit(0);    }    if(ans[y]&&ans[z]&&ans[m]){        if((ans[y]+ans[z]+add)%n!=ans[m]){            return;        }        else{            if(ans[y]+ans[z]+add>=n){                dfs(x+1,1);            }            else{                dfs(x+1,0);            }        }    }    else if(ans[y]&&ans[z]){        ans[m]=ans[y]+ans[z]+add;        if(ans[m]>=n){            ans[m]%=n;            if(use[ans[m]]){                return;            }            use[ans[m]]=1;            dfs(x+1,1);        }        else{            if(use[ans[m]]){                return;            }            use[ans[m]]=1;            dfs(x+1,0);        }        use[ans[m]]=0;        ans[m]=0;    }    else if(ans[y]&&ans[m]){        ans[z]=ans[m]-ans[y]-add;        if(ans[z]<0){            ans[z]+=n;            if(use[ans[z]]){                return;            }            use[ans[z]]=1;            dfs(x+1,1);        }        else{            if(use[ans[z]]){                return;            }            use[ans[z]]=1;            dfs(x+1,0);        }        use[ans[z]]=0;        ans[z]=0;    }    else if(ans[z]&&ans[m]){        ans[y]=ans[m]-ans[z]-add;        if(ans[y]<0){            ans[y]+=n;            if(use[ans[y]]){                return;            }            use[ans[y]]=1;            dfs(x+1,1);        }        else{            if(use[ans[y]]){                return;            }            use[ans[y]]=1;            dfs(x+1,0);        }        use[ans[y]]=0;        ans[y]=0;    }    else if(ans[z]){        for(int i=0;i<n;i++){            if(!use[i]){                ans[y]=i;                use[i]=1;                ans[m]=ans[y]+ans[z]+add;                if(ans[m]>=n){                    ans[m]%=n;                    if(use[ans[m]]){                        return;                    }                    use[ans[m]]=1;                    dfs(x+1,1);                }                else{                    if(use[ans[m]]){                        return;                    }                    use[ans[m]]=1;                    dfs(x+1,0);                }                use[ans[m]]=0;                ans[m]=0;                use[i]=0;                ans[y]=0;            }        }     }    else if(ans[y]){        for(int i=0;i<n;i++){            if(!use[i]){                ans[z]=i;                use[i]=1;                ans[m]=ans[y]+ans[z]+add;                if(ans[m]>=n){                    ans[m]%=n;                    if(use[ans[m]]){                        return;                    }                    use[ans[m]]=1;                    dfs(x+1,1);                }                else{                    if(use[ans[m]]){                        return;                    }                    use[ans[m]]=1;                    dfs(x+1,0);                }                use[ans[m]]=0;                ans[m]=0;                use[i]=0;                ans[z]=0;            }        }     }    else if(ans[m]){        for(int i=0;i<n;i++){            if(!use[i]){                ans[y]=i;                use[i]=1;                ans[z]=ans[m]-ans[y]-add;                if(ans[z]<0){                    ans[z]+=n;                    if(use[ans[z]]){                        return;                    }                    use[ans[z]]=1;                    dfs(x+1,1);                }                else{                    if(use[ans[z]]){                        return;                    }                    use[ans[z]]=1;                    dfs(x+1,0);                }                ans[y]=0;                use[i]=0;                use[ans[z]]=0;                ans[z]=0;            }        }    }    else{        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                if(i!=j&&!use[i]&&!use[j]){                    use[i]=1;                    use[j]=1;                    ans[x]=i;                    ans[y]=j;                    ans[m]=ans[x]+ans[z]+add;                    if(ans[m]>n){                        ans[m]-=n;                        if(use[ans[m]]){                            return;                        }                        use[ans[m]]=1;                        dfs(x+1,1);                    }                    else{                        if(use[ans[m]]){                            return;                        }                        use[ans[m]]=1;                        dfs(x+1,0);                    }                    use[i]=0;                    use[j]=0;                    use[ans[m]]=0;                    ans[x]=0;                    ans[y]=0;                    ans[m]=0;                }            }        }    }}int main(){    freopen("P1092.txt","r",stdin);    scanf("%d",&n);    scanf("%s",&a);    scanf("%s",&b);    scanf("%s",&c);    for(int i=n-1;i>=0;i--){        for(int j=n-1;j>=0;j--){            if(i==j&&a[n-1]==b[n-1]){                int x=a[n-1];                ans[x]=i;                use[i]=1;                dfs(1,0);                ans[x]=0;                use[i]=0;            }            else if(i!=j){                int x=a[n-1],y=b[n-1];                ans[x]=i;                ans[y]=j;                use[i]=1;                use[j]=1;                dfs(1,0);                ans[x]=0;                ans[y]=0;                use[i]=0;                use[j]=0;            }        }    }}

(不要抄上面那个代码,那个是错的,如果您知道怎么更改,请告诉我)

将近250行的代码啊,思想简单,就是把它从最后一位开始枚举,每次有八种可能性(知道3个x1,知道2个x3,知道1个x3,全部不知道x1),从最后一位向前枚举,直到第一位,如果全部正确就输出答案
但是写完过后我就丧失了调试它的欲望(我写了一堆什么??),结果一提交就没有输出(这么长的代买怎么找错啊),于是觉得自己太菜了,需要标程来帮助我


正确的部分

下面的应该是对的

当然啦,在一番学习后,才发现这样暴力去写是不行的
我们可以直接去每一位先搜a[i]的数值再搜b[i]的数值(妈耶这么简单的吗?)
剪枝也十分易懂,就是最高位不进位,还有每次搜到一位就检查一下前面的几位,如果有一位三个数都被搜到了,那我们就判断这是否合法(((a+b+1)%n==c)||((a+b)%n==c)?1:0)
原来这么简单的啊……

#include<bits/stdc++.h>using namespace std;char a[200],b[200],c[200];int d[300],n;bool f[200];void dfs(int x,int jw,int star){    int i,j;    if(x==0){        for(i=(int)'A';i<=(int)('A'+n-1);i++){             cout<<d[i]<<' ';        }        exit(0);    }    if(d[a[1]]+d[b[1]]>=n){        return;    }    for(i=x-1;i>=1;i--){        if(d[a[i]]>=0&&d[b[i]]>=0&&d[c[i]]>=0){            if((d[a[i]]+d[b[i]])%n!=d[c[i]]&&(d[a[i]]+d[b[i]]+1)%n!=d[c[i]]){                return;            }        }    }    if(d[a[x]]>=0&&d[b[x]]>=0&&d[c[x]]>=0){        if((d[a[x]]+d[b[x]]+jw)%n!=d[c[x]]){            return;        }        else{            dfs(x-1,(d[a[x]]+d[b[x]]+jw)/n,1);            return;        }    }    if(star==1){        if(d[a[x]]>=0){            dfs(x,jw,2);        }        else{            for(i=0;i<n;i++){                if(!f[i]){                    d[a[x]]=i;                    f[i]=1;                    dfs(x,jw,2);                    d[a[x]]=-1;                    f[i]=0;                }            }        }      }    if(star==2){        if(d[b[x]]>=0){            dfs(x,jw,3);        }        else{            for(i=0;i<n;i++){                if(!f[i]){                    d[b[x]]=i;                    f[i]=1;                    dfs(x,jw,3);                    d[b[x]]=-1;                    f[i]=0;                }            }         }    }    if(star==3){        int choice=(d[a[x]]+d[b[x]]+jw)%n;        if(d[c[x]]>=0){            if(d[c[x]]==choice){                dfs(x-1,(d[a[x]]+d[b[x]]+jw)/n,1);                return;            }            else return;        }        if(f[choice]){            return;        }        d[c[x]]=choice;        f[choice]=1;        dfs(x-1,(d[a[x]]+d[b[x]]+jw)/n,1);        d[c[x]]=-1;        f[choice]=0;    }}int main(){    cin>>n>>(a+1)>>(b+1)>>(c+1);    memset(d,-1,sizeof(d));    dfs(n,0,1);}

这样就可以AC啦