[NOIP2004 虫食算]

半腔热情 提交于 2020-02-04 09:52:50

[关键字]:搜索

[题目大意]:不说了,自己找吧……

//===================================================================

[分析]:首先按照字母出现的顺序进行搜索,搜索每个字母分别代表什么数字。在每次搜索时都要剪枝,就是把当前的已知字母带到竖式中算一遍,如果出现矛盾情况就剪枝。矛盾情况就是:

1、同一列三个数都已知但(a+b)%n!=c

2、已知两个数但计算出的第三个数已经被其他字母占用。注意这里要处理进位的情况。

[代码]:

View Code
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;char s[4][27];int n,now;int a[27],b[27],c[27];bool goal;bool Judge(){     //for (int i=0;i<n;++i) printf("%d ",b[i]);     //printf("\n");     int temp=0,k=0;     for (int i=n-1;i>=0;--i)     {         temp=(b[s[1][i]-'A']+b[s[2][i]-'A']+k)%n;         k=(b[s[1][i]-'A']+b[s[2][i]-'A']+k)/n;         if (temp!=b[s[3][i]-'A']) return 0;     }     return 1;}     bool Cleck(){     int temp,t1,t2,t3;     for (int i=n-1;i>=0;--i)     {         t1=s[1][i]-'A',t2=s[2][i]-'A',t3=s[3][i]-'A';         if (b[t1]!=-1 && b[t2]!=-1 && b[t3]!=-1)             if ((b[t1]+b[t2]+1)%n==b[t3] || (b[t1]+b[t2])%n==b[t3]) continue; else return 0;         if (b[t1]!=-1 && b[t2]!=-1)         {                       temp=(b[t1]+b[t2])%n;                       if (a[temp]==-1 || a[(temp+1)%n]==-1) continue; else return 0;         }         if (b[t1]!=-1 && b[t3]!=-1)         {                       temp=b[t3]-b[t1];                       if (temp>=0 && a[temp]==-1) continue;                       temp+=n;                       if (temp>=0 && a[temp]==-1) continue;                       temp=b[t3]-b[t1]-1;                       if (temp>=0 && a[temp]==-1) continue;                       temp+=n;                       if (temp>=0 && a[temp]==-1) continue;                       return 0;         }         if (b[t2]!=-1 && b[t3]!=-1)         {                       temp=b[t3]-b[t2];                       if (temp>=0 && a[temp]==-1) continue;                       temp+=n;                       if (temp>=0 && a[temp]==-1) continue;                       temp=b[t3]-b[t2]-1;                       if (temp>=0 && a[temp]==-1) continue;                       temp+=n;                       if (temp>=0 && a[temp]==-1) continue;               return 0;         }     }     return 1;}void DFS(int k){     if (k>n)     {             if (Judge()) goal=1;             return;     }     for (int i=n-1;i>=0;--i)         if (a[i]==-1)         {                      a[i]=c[k];                      b[c[k]]=i;                      //printf("%d %d %d\n",k,c[k],b[c[k]]);                      if (Cleck()) DFS(k+1);                      if (goal) return;                      a[i]=-1;                      b[c[k]]=-1;         }}int main(){    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);    scanf("%d",&n);    scanf("%s",s[1]);    scanf("%s",s[2]);    scanf("%s",s[3]);    memset(a,255,sizeof(a));    for (int i=n-1;i>=0;--i)        for (int j=1;j<=3;++j)            if (b[s[j][i]-'A']==0)            {                                b[s[j][i]-'A']=-1;                                c[++now]=s[j][i]-'A';                                //printf("%d %c %d\n",now,s[j][i],c[now]);            }    //for (int i=1;i<=n;++i) printf("%d\n",c[i]);    DFS(1);    for (int i=0;i<n;++i) printf("%d ",b[i]);    return 0;}



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!