题目描述
著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字。 例如:
+ 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!=s1,j(i!=j)。
保证至多有一组解。
输出格式
第一行输出各个字母表示什么数,格式如:L=0 K=1
⋯ 按给出的字母顺序排序。不同字母必须代表不同数字。
第二行输出加法运算是几进制的。
若不可能组成加法表,则应输出 ERROR!
。
测试样例
输入
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
输出
L=0 K=1 V=2 E=3
4
解题方法
1.这个题目有一个小技巧,就是单个字母所代表的数,就是这个字母单独出现的次数减一
2.当统计完所有单独字母的数值之后,下面就要判断进位,如果两个字母的和等于他们的组合的数值,说明整个进制表合理,则输出n-1,否则输出ERROR!(一定记得后面还有个!)
AC代码
#include<bits/stdc++.h>
using namespace std;
char str[10][10][5];
//所有的大写字母ASCII码在100以内
int num[100]={0};
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>str[i][j];
}
}
//记录单个字母出现的次数
for(int i=2;i<=n;i++)
{
for(int j=2;j<=n;j++)
{
if(strlen(str[i][j])==1) num[str[i][j][0]]++;
}
}
//计算有进位的单个字母的次数,判断是否有错
for(int i=2;i<=n;i++)
{
for(int j=2;j<=n;j++)
{
int x1 = num[str[i][1][0]] - 1;
int x2 = num[str[1][j][0]] - 1;
//z来记录进制转换之后的和
int z = 0;
int l = strlen(str[i][j]);
for(int k=0;k<l;k++)
{
int cnt = num[str[i][j][k]] - 1;
z = z*(n-1) + cnt;
}
//判断是否合理
if(x1+x2!=z)
{
cout<<"ERROR";
return 0;
}
}
}
//输出进制
for(int i=2;i<=n;i++)
{
cout<<str[1][i][0]<<"="<<num[str[1][i][0]]-1<<" ";
}
cout<<endl<<n-1;
return 0;
}