zoukankan      html  css  js  c++  java
  • 【NOIP2004】虫食算

    Description

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

      43#9865#045
    +   8468#6633
      44445509678

    其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是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

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

    Output

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

    Sample Input

    5
    ABCED
    BDACE
    EBBAA

    Sample Output

    1 0 3 4 2

    Hint

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

    搜索每个字母所表示的数字。 考虑搜索的顺序,因为有进位的影响,先搜在最后一位出现的字母,这样会使后面的可行性剪枝的效果更好。 可行性剪枝 1.从后往前,依次判断。若某一位的三个字母已经搜完,那么就判断一下是否是对的。 2.利用方程思想,x+y=z,知道其中两个之后可以得出第三个的可能的值,然后判断这个值是否已经被用过。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<cctype>
      9 #include<cfloat>
     10 #include<vector>
     11 #include<map>
     12 #define RG register
     13 using namespace std;
     14 char a[100],b[100],c[100],d[100];
     15 int k[100],n,flag=0,has[100],cf[100];
     16 bool CUT()
     17 {
     18     for (int i=n-1;i>=0;i--)
     19     {//a+b==c;
     20       int p=k[a[i]-'A'],q=k[b[i]-'A'],r=k[c[i]-'A'];
     21       if (p==-1 || q==-1 || r==-1) continue;
     22       if (!((p+q)%n==r || (p+q+1)%n==r)) return true;
     23     }
     24     for (int i=n-1;i>=0;i--)
     25     {//a+?==c;
     26       int p=k[a[i]-'A'],q=k[b[i]-'A'],r=k[c[i]-'A'];
     27       if (!(p!=-1 && q==-1 && r!=-1)) continue;
     28       int p1=(r-p+n)%n,p2=(r-p-1+n)%n;
     29       if (has[p1] && has[p2]) return true;
     30     }
     31     for (int i=n-1;i>=0;i--)
     32     {//?+b==c;
     33       int p=k[a[i]-'A'],q=k[b[i]-'A'],r=k[c[i]-'A'];
     34       if (!(p==-1 && q!=-1 && r!=-1)) continue;
     35       int p1=(r-q+n)%n,p2=(r-q-1+n)%n;
     36       if (has[p1] && has[p2]) return true;
     37     }
     38     for (int i=n-1;i>=0;i--)
     39     {//a+b==?;
     40        int p=k[a[i]-'A'],q=k[b[i]-'A'],r=k[c[i]-'A'];
     41         if (!(p!=-1 && q!=-1 && r==-1)) continue;
     42         int p1=(p+q)%n;
     43         int p2=(p+q+1)%n;
     44         if (has[p1] && has[p2]) return true;
     45     }
     46     return false;
     47 }
     48 
     49 bool CUT1()
     50 {
     51   int u=0;
     52   for(int i=n-1;i>=0;i--)
     53     {
     54       int p=k[a[i]-'A'],q=k[b[i]-'A'],r=k[c[i]-'A'];
     55       if(p==-1 || q==-1 || r==-1) return 0;
     56       if(p+q+u>=n) {
     57     if((p+q+u-n)!=r) return 1;
     58     u=1;
     59       }
     60       else {
     61     if((p+q+u)!=r) return 1;
     62     u=0;
     63       }
     64     }
     65   return 0;
     66 }
     67 void search(int x)
     68 {
     69   int u=d[x]-'A';
     70   if(flag) return;
     71   if(CUT1()) return;
     72   if(CUT()) return;
     73   if(x==n){
     74     for(int i=0;i<n;i++)
     75       printf("%d ",k[i]);
     76     flag=1;
     77     return;
     78   }
     79   for(int i=n-1;i>=0;i--)
     80     {
     81       if(has[i]) continue;
     82       k[u]=i;
     83       has[i]=1;
     84       search(x+1);
     85       k[u]=-1;
     86       has[i]=0;
     87     }
     88 }
     89 int main()
     90 {
     91   freopen("!.in","r",stdin);
     92   freopen("!.out","w",stdout);
     93   scanf("%d",&n);scanf("%s",a);scanf("%s",b);scanf("%s",c);
     94   memset(k,-1,sizeof(k));
     95   for(int i=n-1,j=0;i>=0;i--)
     96     {
     97       char u1=a[i],u2=b[i],u3=c[i];
     98       if(!cf[u1-'A']) d[j]=u1,j++,cf[u1-'A']=1;
     99       if(!cf[u2-'A']) d[j]=u2,j++,cf[u2-'A']=1;
    100       if(!cf[u3-'A']) d[j]=u3,j++,cf[u3-'A']=1;
    101     }
    102   search(0);
    103   return 0;
    104 }
  • 相关阅读:
    配置gulpfile,添加task任务
    requestAnimationFrame初探
    实现图片的预加载和懒加载
    jquery实现复制到粘贴板
    微信H5页面遇到的一些问题
    js实现日历的简单算法
    handlebars.js的运用与整理
    倒计时插件
    div 模拟<select>事件
    Emacs添加主题插件(Win系统)
  • 原文地址:https://www.cnblogs.com/pantakill/p/7130196.html
Copyright © 2011-2022 走看看