洛谷千题详解 | P1013 [NOIP1998 提高组] 进制位【C++语言】

博主主页:Yu·仙笙

专栏地址:洛谷千题详解

目录

题目描述

输入格式

输出格式

输入输出样例

解析:

1·字符串与

2·解题部分

(1) 对于任意字母L的一行,两位数个数等于L的值;

x+y=x+(z-(z-y))=x+z-(z-y)=z+(x-(z-y))x+y=x+(z−(z−y))=x+z−(z−y)=z+(x−(z−y))

(2)对于给出数据的合理性

有n行n列表示n-1个个位数(n<=9)(第1行第1列都是表头)

一定是能加出两位数来的:

进制z=n-1

(3)判错

C++源码:

C++源码2:

C++源码3:


------------------------------------------------------------------------------------------------------------------------------- 

 ------------------------------------------------------------------------------------------------------------------------------- 

题目描述

著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字。 例如:

+    L    K      V      E
L    L    K      V      E
K    K    V      E     KL
V    V    E     KL     KK
E    E    KL    KK     KV

其含义为:

L+L=L,L+K=K,L+V=V,L+E=E

K+L=K,K+K=V,K+V=E,K+E=KL

.............................................................

E+E=KV

根据这些规则可推导出:L=0,K=1,V=2,E=3。

同时可以确定该表表示的是 4 进制加法。

 ------------------------------------------------------------------------------------------------------------------------------- 

输入格式

第一行一个整数 n (3≤n≤9)表示行数。

以下 n 行,每行包括 n 个字符串,每个字符串间用空格隔开。)

若记si,j​ 表示第 i 行第 j 个字符串,数据保证 s1,1​=+,si,1​=s1,i​,∣si,1​∣=1,si,1​=sj,1​ (i=j)。

保证至多有一组解。

 ------------------------------------------------------------------------------------------------------------------------------- 

输出格式

第一行输出各个字母表示什么数,格式如:L=0 K=1 ........... 按给出的字母顺序排序。不同字母必须代表不同数字。

第二行输出加法运算是几进制的。

若不可能组成加法表,则应输出 ERROR!

 ------------------------------------------------------------------------------------------------------------------------------- 

输入输出样例

输入 #1

5
+ L K V E
L L K V E
K K V E KL
V V E KL KK
E E KL KK KV

输出 #1

L=0 K=1 V=2 E=3
4

 ------------------------------------------------------------------------------------------------------------------------------- 

解析:

p1013 (一篇超详细且有扩展有证明的全面题解) 题面:
著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字。 例如:
+. L K V E
L L K V E
K K V E KL
V V E KL KK
E E KL KK KV
其含义为:

L+L=L,L+K=K,L+V=V,L+E=E
K+L=K,K+K=V,K+V=E,K+E=K

…… E+E=KV

根据这些规则可推导出:L=0,K=1,V=2,E=3
同时可以确定该表表示的是4进制加法

输入 n(n≤9)表示行数。

以下n行,每行包括n个字符串,每个字串间用空格隔开。(字串仅有一个为‘+’号,其它都由大写字母组成)

输出 ① 各个字母表示什么数,格式如:L=0,K=1,……按给出的字母顺序。

② 加法运算是几进制的。

③ 若不可能组成加法表,则应输出“ERROR!”
解题:

1·字符串与<map>

<map>:
首先,map的申明方式:
map<key,value> name

是一个键值对key——value的映射。实现是由内部的一棵以key为关键码的红黑树。

而key和value是任意类型,其中key必须定义“小于号”运算符

例如:

#### map<long long , bool> vis;    
#### map<string , int> hash;    
#### map<pair<int ,int>,vector<int> > test        
所以当我们遇到字符串类型的问题时,便可以用map作hash表,建立字符型(char,string……)key到整型(int,long long ……)value的映射,但平衡树(logn)略慢于hash函数实现的hash表    

相关函数:

size/empty/clear/begin/end (元素个数,判空,清空,首(迭代器),尾(迭代器))

//迭代器都关系二元组pair<key,value>

insert/erase(插入,删除)(迭代器)

find 对于 name.find(x):表示在变量名为name的map中查找key为x的二元组,若不存在·,返回name.end() //(logn)

name[key] 返回key映射的value

//借此可以方便的获得key对应的value,并可以进行赋值(使用之前先用find检查存在性)

2·解题部分


首先最靠谱的解法:先将0,1判断出来,0是和等于某数本身的,1是两位数的十位,然后推出其他数字
(比如找到加数为1的那行,得到若干形如x+1=y的式子,于是连一条从x到y的边,由于我们知道0是那个数字,最后就可以依据边的连接关系推出所有字母…… 最后再检验检验,错了就输出 ERROR! 即可。)
并判断对不对……


思考在十进制下,0+9=9,该行无二位数;
1+9=10,1+8=9,该行有一个二进制数;
2+9=11,2+8=10,2+7=9,该行有两个二进制数; 我们可以得出

(1) 对于任意字母L的一行,两位数个数等于L的值;

证明,设L=x,设对应某一列的值为y,进制为z,则有:

x+y=x+(z-(z-y))=x+z-(z-y)=z+(x-(z-y))x+y=x+(z−(z−y))=x+z−(z−y)=z+(x−(z−y))

因为z加上一个大于0的数一定是一个两位数,换过来,如果要z+(x-(z-y))是一个两位数,则x-(z-y)>=0,所以x-(z-y)=0时恰好取得最后一个两位数,也正好对应了x的值。

  • 另外,特别观察对于z本身是不是两位数的问题:
    (其实本题n<=9并不需要想这么多)
    例如z=4,如题四个数分别是0,1,2,3,此时,0+3=3(x=0,y=3,z=4),1+3=10(x=1,y=3,z=4),发现满足上述性质
    这样我们便有了计算每个字母是多少的方法; 那么如何判断进制?
    严肃的问题来了。

(2)对于给出数据的合理性

我们发现,题目并没保证给出的数据都是像样例这样整齐漂亮而有规律的,于是我们面临了几个情况:

  1. 是否满足进制内的数都有?
  2. 某一字母是否可能超出进制?

->我们所找的两位数的存在问题
对于这两个问题,我们先探究加法表的存在性问题:
首先题目隐藏信息:

     进制一定大于最大字母(不然就出锅了)

所以我们就获得了条件:数位最高为2,十位最大为1
(因为有两位数所以必定有1,有1所以0~n-2必定都有 (下方证明)
这样就**满足进制内的数都有,并且不会有某一字母超出进制 **
这就好办了,整理一下现在我们拥有的信息:

有n行n列表示n-1个个位数(n<=9)(第1行第1列都是表头)

一定是能加出两位数来的:

  还是先举例子再证明->n=4来列表
  如果表中没有两位数
  + 0  1  2 
  0 0  1  2
  1 1  2  3
  2 2  3  4
  明显出现了不存在的字母
  那假如是设进制z=4呢?对于z=4并且没有两位数的表:
  + 0 1 2
  0 0 1 2
  1 1 2 3
  2 2 3 4
  明显表中不但不得不出现4,但4已经应该进位,而且还是存在
  表头中不存在的字母的情况
  下面规范的证明一下:
  设在表n中,最大个位数X,进制z
  设表中无两位数
  则X < z/2  此时有(X+X)作为表中最大数位个位数且小于
  进制z,于假设最大个位数X冲突,所以表中无两位数的假设不
  成立。
 

进制z=n-1

由上面的证明的第二幅图可以看出
如果只是将最下角的4作为两位数10,加法表中存在3,而表头中
最大数为2,仍然不成立,所以这幅图四进制明显不对,由于表头
中最大值是2,所以表中大于二便要进位,即进制z=3,而n=4,
z=n-1=X+1成立。
规范证明:已知表头中有n-1个个位数,设最大个位数X,由
(1)的逆定理,L的值等于两位数个数,则正好存在一个两位数
时,L=1,并且两位数是这一行中最大的数,即等于L+X=1+X,
X=n-2,L+X=n-1,因为X本身已经是最大的个位数,L=1又是除0
外最小的个位数,所以L+X=z,证得z=n-1

这样我们的信息就完整了,解决题目
z=n-1直接炸出进制,然后统计每一行两位数个数计算字母所代表的数字(** 并且这里两位数的高位上必定是1,->两个个位无论如何加不爆十位啊** )

(3)判错

怎么样构不成加法表?

对于一个数值,若某字母已经符合过,那一定是错误的

超级好懂的无脑法:再把整个矩阵遍历一遍,看看每一个位置上的字母对不对(注意字母顺序)

对于一个0,1以外的字母,只会在+0时出现,即一行中除表头只出现一次

然而这个特判写起来很繁琐,怎么快捷的判错??(这里其他题解大概讲了,但因为这种判错确实是较优的所以仍然选择这种,不再给出过多证明): 对比两种计算字母值方法的结果是否相同
##### 另一种计算字母值的方法:对于字母X,X=n-2-(X在两位数的个位上出现次数)(还是给一句吧不然难受,对于n-2上面已经出现过了,是最大的个位数,而X在两位数个位出现次数即二位数(z+X)的个数,将图左下角到右上角做对角线就能发现分布规律)

 ------------------------------------------------------------------------------------------------------------------------------- 

C++源码:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define fu(i,q,w) for(register int i=q;i<=w;i++)
#define fd(i,q,w) for(register int i=q;i>=w;i--)
using namespace std;
typedef long long ll;
inline int read(){
    int ret=0,f=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;
    while(c>='0'&&c<='9')ret=ret*10+(c-'0'),c=getchar();
    return ret*f;
}
char word[10];//记录字母 
char check[10];//检查重复 
string numx,numy;//储存输入数据、检查重复 
map<char,int> two;//一行中两位数个数 
map<char,int> tone;//存字母在两位数个位出现几次 
int n;
void in(){
    n=read();
    cin>>numx;//"+"特判输入 
    fu(i,1,n-1){cin>>numx,word[i]=numx[0];}// 第一行存表头的每个字母 
    fu(i,1,n-1)//从第二行开始 
    fu(j,1,n){cin>>numx;
            
        if(j!=1&&j!=2)//表头不算
        if(numx==numy){printf("ERROR!");exit(0);}//发现重复输入一定不对 
        numy=numx; //前后比,不要全行比
        if(numx.size()==2){//统计两位数个数 
            two[word[i]]++;tone[numx[1]]++;
        }
    }
}
void solve(){
    fu(i,1,n-1)
    if(two[word[i]]!=n-2-tone[word[i]]){printf("ERROR!");exit(0);}
    //比较两种算法的结果是否相同
 	fu(i,1,n-1)
 	cout<<word[i]<<'='<<two[word[i]]<<' ';
 	printf("\n");
 	printf("%d",n-1);
 	
 	
    }
int main(){
    in();
    solve();
    return 0; 
    
}
 

 ------------------------------------------------------------------------------------------------------------------------------- 

C++源码2:

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n;
string a[100][100];
int l[100];
char sum[100];
int w[1100];
int ll,f;
int flag;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>a[i][j];
    for(int i=2;i<=n;i++)
    {	
        sum[i]=a[1][i][0];
    }
    if(n==3) 
    {
        for(int i1=0;i1<n-1;i1++)
        {
            for(int i2=0;i2<n-1;i2++)
            {
                flag=0;
                if(i1!=i2)
                {
                    w[sum[2]]=i1;
                    w[sum[3]]=i2;
                    for(int j=2;j<=n;j++)
                    {
                        for(int k=2;k<=n;k++)
                        {
                            ll=a[j][k].size();
                            f=1;
                            for(int kk=0;kk<ll;kk++)
                                f*=w[a[j][k][kk]];
                            f%=n-1;
                            if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                        }
                    }
                    if(flag==0)
                    {
                        cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<endl<<n-1;
                        return 0;
                    }
                }
            }
        }
    }
        if(n==4) 
        {
            for(int i1=1;i1<n-1;i1++)
            {
                for(int i2=2;i2<n-1;i2++)
                {
                    for(int i3=0;i3<n-1;i3++) 
                    {
                        flag=0;
                        if(i1!=i2&&i1!=i3&&i2!=i3)
                        {
                            w[sum[2]]=i1;
                            w[sum[3]]=i2;
                            w[sum[4]]=i3;
                            for(int j=2;j<=n;j++)
                            {
                                for(int k=2;k<=n;k++)
                                {
                                    ll=a[j][k].size();
                                    f=1;
                                    for(int kk=0;kk<ll;kk++)
                                     {
                                        f*=w[a[j][k][kk]];
                                    }
                                    f%=n-1;
                                    if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                }
                            }
                            if(flag==0)
                            {
                                cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<endl<<n-1;
                                return 0;
                            }
                        }
                    }
                
                }
            }
        }
        if(n==5) 
        {
            for(int i1=0;i1<n-1;i1++)
            {
                for(int i2=0;i2<n-1;i2++)
                {
                    for(int i3=0;i3<n-1;i3++) 
                    {
                        for(int i4=0;i4<n-1;i4++)
                        {
                            flag=0;
                            if(i1!=i2&&i1!=i3&&i1!=i4&&i2!=i3&&i2!=i4&&i3!=i4)
                            {
                                w[sum[2]]=i1;
                                w[sum[3]]=i2;
                                w[sum[4]]=i3;
                                w[sum[5]]=i4;
                                for(int j=2;j<=n;j++)
                                {
                                    for(int k=2;k<=n;k++)
                                    {
                                        ll=a[j][k].size();
                                        f=1;
                                        for(int kk=0;kk<ll;kk++)
                                            f*=w[a[j][k][kk]];
                                        f%=n-1;
                                        if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                    }
                                }
                                if(flag==0)
                                {
                                    cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<" "<<a[1][5]<<"="<<i4<<endl<<n-1;
                                    return 0;
                                }
                                }
                            }
                        }
                    }
                
                }
            }
        if(n==6) 
        {
            for(int i1=0;i1<n-1;i1++)
            {
                for(int i2=0;i2<n-1;i2++)
                {
                    for(int i3=0;i3<n-1;i3++) 
                    {
                        for(int i4=0;i4<n-1;i4++)
                        {
                            for(int i5=0;i5<n-1;i5++)
                            {
                            
                                flag=0;
                                if(i1!=i2&&i1!=i3&&i1!=i4&&i1!=i5&&i2!=i3&&i2!=i4&&i2!=i5&&i3!=i4&&i3!=i5&&i4!=i5)
                                {
                                    w[sum[2]]=i1;
                                    w[sum[3]]=i2;
                                    w[sum[4]]=i3;
                                    w[sum[5]]=i4;
                                    w[sum[6]]=i5;
                                    for(int j=2;j<=n;j++)
                                    {
                                        for(int k=2;k<=n;k++)
                                        {
                                            ll=a[j][k].size();
                                            f=1;
                                            for(int kk=0;kk<ll;kk++)
                                                f*=w[a[j][k][kk]];
                                            f%=n-1;
                                            if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                        }
                                    }
                                    if(flag==0)
                                    {
                                        cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<" "<<a[1][5]<<"="<<i4<<" "<<a[1][6]<<"="<<i5<<endl<<n-1;
                                        return 0;
                                    }
                                }
                            }
                        }
                    }
                
                }
            }
        }
        if(n==7) 
        {
            for(int i1=0;i1<n-1;i1++)
            {
                for(int i2=0;i2<n-1;i2++)
                {
                    for(int i3=0;i3<n-1;i3++) 
                    {
                        for(int i4=0;i4<n-1;i4++)
                        {
                            for(int i5=0;i5<n-1;i5++)
                            {
                                for(int i6=0;i6<n-1;i6++)
                                {	

                                    flag=0;
                                    if(i1!=i2&&i1!=i3&&i1!=i4&&i1!=i5&&i1!=i6&&i2!=i3&&i2!=i4&&i2!=i5&&i2!=i6&&i3!=i4&&i3!=i5&&i3!=i6&&i4!=i5&&i4!=i6&&i5!=i6)
                                    {
                                        w[sum[2]]=i1;
                                        w[sum[3]]=i2;
                                        w[sum[4]]=i3;
                                        w[sum[5]]=i4;
                                        w[sum[6]]=i5;
                                        w[sum[7]]=i6;
                                        for(int j=2;j<=n;j++)
                                        {
                                            for(int k=2;k<=n;k++)
                                            {
                                                ll=a[j][k].size();
                                                f=1;
                                                for(int kk=0;kk<ll;kk++)
                                                    f*=w[a[j][k][kk]];
                                                f%=n-1;
                                                if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                                }
                                            }
                                        if(flag==0)
                                        {
                                            cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<" "<<a[1][5]<<"="<<i4<<" "<<a[1][6]<<"="<<i5<<" "<<a[1][7]<<"="<<i6<<endl<<n-1;
                                            return 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                
                }
            }
        }
        if(n==8) 
        {
            for(int i1=0;i1<n-1;i1++)
            {
                for(int i2=0;i2<n-1;i2++)
                {
                    for(int i3=0;i3<n-1;i3++) 
                    {
                        for(int i4=0;i4<n-1;i4++)
                        {
                            for(int i5=0;i5<n-1;i5++)
                            {
                                for(int i6=0;i6<n-1;i6++)
                                {	

                                    for(int i7=4;i7<n-1;i7++)
                                    {
                                        flag=0;
                                        if(i1!=i2&&i1!=i3&&i1!=i4&&i1!=i5&&i1!=i6&&i1!=i7&&i2!=i3&&i2!=i4&&i2!=i5&&i2!=i6&&i2!=i7&&i3!=i4&&i3!=i5&&i3!=i6&&i3!=i7&&i4!=i5&&i4!=i6&&i4!=i7&&i5!=i6&&i5!=i7&&i6!=i7)
                                        {
                                            w[sum[2]]=i1;
                                            w[sum[3]]=i2;
                                            w[sum[4]]=i3;
                                            w[sum[5]]=i4;
                                            w[sum[6]]=i5;
                                            w[sum[7]]=i6;
                                            w[sum[8]]=i7;
                                            for(int j=2;j<=n;j++)
                                            {
                                                for(int k=2;k<=n;k++)
                                                {
                                                    ll=a[j][k].size();
                                                    f=1;
                                                    for(int kk=0;kk<ll;kk++)
                                                        f*=w[a[j][k][kk]];
                                                    f%=n-1;
                                                    if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                                }
                                            }
                                            if(flag==0)
                                            {
                                                cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<" "<<a[1][5]<<"="<<i4<<" "<<a[1][6]<<"="<<i5<<" "<<a[1][7]<<"="<<i6<<" "<<a[1][8]<<"="<<i7<<endl<<n-1;
                                                return 0;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                
                }
            }
        }
        if(n==9) 
        {
        //枚举8个字母的值 
        for(int i1=0;i1<n-1;i1++)
        {
            for(int i2=0;i2<n-1;i2++)
            {
                for(int i3=0;i3<n-1;i3++) 
                {
                    for(int i4=0;i4<n-1;i4++)
                    {
                        for(int i5=0;i5<n-1;i5++)
                        {
                            for(int i6=0;i6<n-1;i6++)
                            {	
                                for(int i7=4;i7<n-1;i7++)
                                {
                                   	for(int i8=0;i8<n-1;i8++)
                                   	{                             	
                                        flag=0;//记录当前情况是否满足
                                        //如果这八个字母的值都不相等 
                                        if(i1!=i2&&i1!=i3&&i1!=i4&&i1!=i5&&i1!=i6&&i1!=i7&&i1!=i8&&i2!=i3&&i2!=i4&&i2!=i5&&i2!=i6&&i2!=i7&&i2!=i8&&i3!=i4&&i3!=i5&&i3!=i6&&i3!=i7&&i3!=i8&&i4!=i5&&i4!=i6&&i4!=i7&&i4!=i8&&i5!=i6&&i5!=i7&&i5!=i8&&i6!=i7&&i6!=i8&i7!=i8)
                                        {
                                        	//w[i]记录字母i所代表的值 
                                            w[sum[2]]=i1;
                                            w[sum[3]]=i2;
                                            w[sum[4]]=i3;
                                            w[sum[5]]=i4;
                                            w[sum[6]]=i5;
                                            w[sum[7]]=i6;
                                            w[sum[8]]=i7;
                                            w[sum[9]]=i8;
                                            //检查每一个字符串 
                                            for(int j=2;j<=n;j++)
                                            {
                                                for(int k=2;k<=n;k++)
                                                {
                                                	//ll为当前字符串的长度 
                                                    ll=a[j][k].size();
                                                    f=1;
                                                    //把当前字符串中每个字母的值乘起来 
                                                    for(int kk=0;kk<ll;kk++)
                                                        f*=w[a[j][k][kk]];
                                                    //取下膜 
                                                    f%=n-1;
                                                    //判断是否满足两字母相加 
                                                    if(f!=(w[sum[k]]+w[sum[j]])%(n-1)) flag=1;
                                                    //如果不满足 flag记为1 
                                                }
                                            }
                                            //如果满足,输出后终止程序 
                                            if(flag==0)
                                            {
                                                cout<<a[1][2]<<"="<<i1<<" "<<a[1][3]<<"="<<i2<<" "<<a[1][4]<<"="<<i3<<" "<<a[1][5]<<"="<<i4<<" "<<a[1][6]<<"="<<i5<<" "<<a[1][7]<<"="<<i6<<" "<<a[1][8]<<"="<<i7<<" "<<a[1][9]<<" "<<i8<<endl<<n-1;
                                                return 0;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
            }
        }
    }
    //枚举时没终止那么便无法满足 
    cout<<"ERROR!";
} 

 ------------------------------------------------------------------------------------------------------------------------------- 

C++源码3:

#include <bits/stdc++.h>
using namespace std;

struct Unsigned{
	int V[99];
	int Size;
};

string Num1[99],Num2[99],Sum[99];
Unsigned Queue1[99],Queue2[99];
map<char,bool> Visited;
map<char,int> Judge2;
Unsigned Queue3[99];
string Map[99][99];
int ACanswer[99];
Unsigned Judge3;
bool Used[99];
int N,Size,M;
int Top;

bool Judge(void){
	for(int i=1;i<=Size;i++){//一个竖式一个竖式得去比较 
		memset(&Judge3,0,sizeof(Judge3));
		Judge3.Size=max(Queue1[i].Size,Queue2[i].Size);
		for(int j=0;j<Judge3.Size;j++){
			Judge3.V[j]=Judge3.V[j]+Queue1[i].V[j]+Queue2[i].V[j];
			Judge3.V[j+1]=Judge3.V[j]/Top;
			Judge3.V[j]=Judge3.V[j]%Top;
		}//高精度计算出答案
		if(Judge3.V[Judge3.Size]>0)
        	Judge3.Size++;
        if(Judge3.Size!=Queue3[i].Size)
        	return false;//如果两数(两个加数的和,原来按字母枚举出来的和)位数不一样,则答案肯定错误 
        for(int j=0;j<Judge3.Size;j++)
        	if(Judge3.V[j]!=Queue3[i].V[j])
        		return false;//一位一位得去比较,如果不同则错误 
	}
	return true;//答案正确 
}

void Print(void){
	for(int i=2;i<=N;i++){
		int Out=Judge2[Map[1][i][0]];
		cout<<Map[1][i]<<"="<<Out<<" ";
	}
	cout<<endl;
	cout<<Top<<endl;
	exit(0);
}//打出答案

void Made(void){
	memset(&Queue1,0,sizeof(Queue1));
	memset(&Queue2,0,sizeof(Queue2));
	memset(&Queue3,0,sizeof(Queue3));
	for(int i=1;i<=Size;i++){
		for(int j=Num1[i].size()-1;j>=0;j--)//将第一个加数的每一位字符按规则转换为数字
			Queue1[i].V[Queue1[i].Size++]=Judge2[Num1[i][j]];
		for(int j=Num2[i].size()-1;j>=0;j--)//将第二个加数的每一位字符按规则转换为数字
			Queue2[i].V[Queue2[i].Size++]=Judge2[Num2[i][j]];
		for(int j=Sum[i].size()-1;j>=0;j--)//将和的每一位字符按规则转换为数字
			Queue3[i].V[Queue3[i].Size++]=Judge2[Sum[i][j]];
	}
}

void Depth_First_Search(int Last){
	if(Last==N+1){Made();//若所有字母都赋值
		if(Judge()==true)//将字母转换为数字,并判断是否与答案相符 
			Print();//如果相符就输出答案 
		return;//不相符就重新做 
	}
	for(int i=0;i<Top;i++){//枚举每个字母所对应的数 
		if(Used[i]==false){//如果这个数没有用过 
			if(Judge2[Map[1][Last][0]]==-1){//如果这个字母未赋值 
				Used[i]=true;//确定这个数用过 
				Judge2[Map[1][Last][0]]=i;//个这个字母赋值 
				Depth_First_Search(Last+1);//确定下一个字母 
				Judge2[Map[1][Last][0]]=-1;
				Used[i]=false;//回溯 
			}
		}
	}
}

int main(void){
	cin>>N;
	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			cin>>Map[i][j];
	//输入数据 
	for(int i=2;i<=N;i++){
		for(int j=2;j<=N;j++){
			for(int k=0;k<Map[i][j].size();k++)
				if(Visited[Map[i][j][k]]==false)
					Visited[Map[i][j][k]]=true,M++;
			Sum[++Size]=Map[i][j];
			Num1[Size]=Map[i][1];
			Num2[Size]=Map[1][j];
		}
	}
	//统计字母总个数,并储存一个个数字,做成加法竖式 
	for(int i=2;i<=N;i++)
		Judge2[Map[i][1][0]]=-1;
	//Judge2用来存储每个字母所对应的数字,此处应是-1(初始化)
	for(Top=N-1;Top<=M;Top++){
		Depth_First_Search(2);
	}//枚举进制
	cout<<"ERROR!"<<endl;
	//没有可能,输出无解 
	return 0;
}

 ------------------------------------------------------------------------------------------------------------------------------- 

猜你喜欢

转载自blog.csdn.net/djfihhfs/article/details/127706641
今日推荐