题目描述
著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字。 例如:
+ 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=LL+L=L,L+K=KL+K=K,L+V=VL+V=V,L+E=EL+E=E
K+L=KK+L=K,K+K=VK+K=V,K+V=EK+V=E,K+E=KLK+E=KL
…… E+E=KVE+E=KV
根据这些规则可推导出:L=0L=0,K=1K=1,V=2V=2,E=3E=3
同时可以确定该表表示的是4进制加法
//感谢lxylxy123456同学为本题新加一组数据
输入输出格式
输入格式:
nn (n≤9)(n≤9)表示行数。
以下nn行,每行包括nn个字符串,每个字串间用空格隔开。(字串仅有一个为‘+’号,其它都由大写字母组成)
输出格式:
① 各个字母表示什么数,格式如:L=0L=0,K=1K=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
题解:
字母的数量等于进制的大小
判错的时候,可以看一下那个表格右下角的一个等腰三角形,就会发现有一个由两位数字(字母)组成的三角形。
我们验算一下,对于L ,在该三角形的双位字母中的个位中出现了三次,则4-1-3=0 ,L代表的就是零了,然后依次验算n-1-次数,发现都等于实际上的进制数字。
然后我们依旧可以发现,在L这一行里面,没有双位字母出现,所以我们可以给L判0,依次查下去,就会发现,下一行,K有一个双位字母,然后K是1,等等。
由上两条作为判错依据,用map映射来统计这些次数,会方便很多。
#include <iostream>
#include <map>
using namespace std;
map<char, int> a;
map<char, int> total;
char le[10];//letter
string x, y;
int main()
{
int n, i, j;
cin >> n;
cin >> x;
for (i = 1; i <= n - 1;i++) {
cin >> x;
le[i] = x[0];
}//first line
for (i = 1; i <= n - 1;i++) {//这是从第二行到第n-1行的意思
for (j = 1; j <= n;j++) {
cin >> x;
if (x==y&&j!=1&&j!=2) {
//第一列是键,第二列单列无法比较
cout << "ERROR!";
return 0;
}
y = x;
if (x.size()==2) {
a[x[1]]++;//计算该字母在两位数个位上的个数,具体见表的右下角等腰三角形内
total[le[i]]++;//第一行相当于第一列,计算该字母两位数的个数
}
}
}
for (i = 1; i <= n-1;i++) {//对应着上面的1到n-1,这是n-1个字符的意思
if (total[le[i]]!=n-2-a[le[i]]) {//字母总个数为n-1
cout << "ERROR!";
return 0;
}
}
for (i = 1; i <= n-1;i++) {
cout << le[i] << '=' << total[le[i]]<<' ';
}
cout << endl
<< n - 1;
getchar();
getchar();
return 0;
}