zoukankan      html  css  js  c++  java
  • 深度优先搜索 codevs 1064 虫食算

    codevs 1064 虫食算

    2004年NOIP全国联赛提高组

     时间限制: 2 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
    题目描述 Description

     所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:

           43#9865#045
        +    8468#6633
           44445506978

        其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。

        现在,我们对问题做两个限制:

        首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。

        其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我们就取英文字母表午的前N个大写字母来表示这个算式中的0到N-1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N-1)。输入数据保证N个字母分别至少出现一次。



                BADC
          +    CBDA
                DCCC

        上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解,

    输入描述 Input Description

    输入包含4行。第一行有一个正整数N(N<=26),后面的3行每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

    输出描述 Output Description

      输出包含一行。在这一行中,应当包含唯一的那组解。解是这样表示的:输出N个数字,分别表示A,B,C……所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

    样例输入 Sample Input

    5
    ABCED
    BDACE
    EBBAA

    样例输出 Sample Output

    1 0 3 4 2

    数据范围及提示 Data Size & Hint

    对于30%的数据,保证有N<=10;
    对于50%的数据,保证有N<=15;
    对于全部的数据,保证有N<=26。

      1 /*这个题目需要注意的细节很多,尤其是jw[k]==0的回溯一定不能忘记*/
      2 #include<iostream>
      3 using namespace std;
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<cstdlib>
      7 int atos['Z'+1];
      8 char jz[4][30];
      9 bool flag[30]={0};
     10 int n;
     11 int jw[30]={0};
     12 void dfs(int k,int p)
     13 {
     14     for(int i=1;i<=n;++i)
     15     {
     16         if(atos[jz[1][i]]>=0&&atos[jz[2][i]]>=0&&atos[jz[3][i]]>=0)
     17         {
     18             int p=atos[jz[1][i]]+atos[jz[2][i]];
     19             if(p%n!=atos[jz[3][i]]&&(p+1)%n!=atos[jz[3][i]])
     20             return;
     21         }
     22     }
     23     if(k<=0)
     24     {
     25         printf("%d",atos['A']);
     26         for(int i='B';i<='A'+n-1;++i)
     27           printf(" %d",atos[i]);
     28         printf("
    ");
     29         exit(0);
     30     }
     31     if(p==3)
     32     {
     33         int temp=atos[jz[1][k]]+atos[jz[2][k]]+jw[k+1];
     34         if(atos[jz[3][k]]>=0)
     35         {
     36             if(atos[jz[3][k]]==temp)
     37             {
     38                 dfs(k-1,1);
     39             }
     40             else if(atos[jz[3][k]]+n==temp)
     41                  {
     42                      jw[k]=1;
     43                      dfs(k-1,1);
     44                      jw[k]=0;
     45                  }else return;
     46         }
     47         else 
     48         {
     49             if(temp>=n)
     50             {
     51                 jw[k]=1;
     52                 temp-=n;
     53             }
     54             if(!flag[temp])
     55             {
     56                 flag[temp]=true;
     57             atos[jz[3][k]]=temp;
     58             dfs(k-1,1);
     59             flag[temp]=false;
     60             atos[jz[3][k]]=-1;
     61             }
     62             jw[k]=0;/*前面一开始写了一个if(flag[temp]) return 结果jw没被重置,倒数第二组数据,就错了*/
     63         }
     64         
     65     }else if(p==2)
     66     {
     67         if(atos[jz[2][k]]>=0)
     68         {
     69             dfs(k,3);
     70         }
     71         else {
     72             for(int j=0;j<=n-1;++j)
     73             {
     74                 if(!flag[j])
     75                 {
     76                     flag[j]=true;
     77                     atos[jz[2][k]]=j;
     78                     dfs(k,3);
     79                     flag[j]=false;
     80                     atos[jz[2][k]]=-1;
     81                 }
     82             }
     83         }
     84     }
     85     else if(p==1)
     86     {
     87         if(atos[jz[1][k]]>=0)
     88         {
     89             dfs(k,2);
     90         }
     91         else {
     92             for(int j=0;j<=n-1;++j)
     93             {
     94                 if(!flag[j])
     95                 {
     96                     flag[j]=true;
     97                     atos[jz[1][k]]=j;
     98                     dfs(k,2);
     99                     flag[j]=false;
    100                     atos[jz[1][k]]=-1;
    101                 }
    102             }
    103         }
    104     }
    105 }
    106 int main()
    107 {
    108     scanf("%d",&n);
    109     for(int i=1;i<=3;++i)
    110       scanf("%s",jz[i]+1);
    111     memset(atos,-1,sizeof(atos));
    112     dfs(n,1);
    113     return 0;
    114 }
  • 相关阅读:
    模拟乒乓球双打和单打比赛
    关于zip内置函数的应用及在 Python 2 和 3 的不同之处
    计算文本平均列数
    四则运算
    Python跳一跳小游戏
    数据库
    类和正则表达
    带进度条的圆周率计算
    球队预测
    自己的第一个网页
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5592187.html
Copyright © 2011-2022 走看看