题目描述
著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字。 例如:
+ 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:
View Code
L=0 K=1 V=2 E=3
4
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include <string> 5 #include<map> 6 using namespace std; 7 8 struct node { 9 string num; 10 int val; 11 int val_dec; 12 }; 13 node tab[15][15]; 14 map<char,int> group; 15 int n; 16 char one; 17 int _one; 18 19 int main() 20 { 21 scanf("%d", &n); 22 for(int i=1;i<=n;i++) 23 for (int j = 1; j <= n; j++) { 24 cin >> tab[i][j].num; 25 if ((tab[i][j].num).length() > 1) 26 { 27 group[tab[i][j].num[0]] = 1; 28 one = tab[i][j].num[0]; 29 } 30 } 31 for (int i = 1; i <= n; i++) { 32 if (tab[1][i].num[0] == one) 33 { 34 _one = i; 35 break; 36 } 37 } 38 int _idnow=_one,_numbernext = 2; 39 char numbernext; 40 while (_numbernext <= n - 2) { 41 numbernext = tab[_one][_idnow].num[0]; 42 group[numbernext] = _numbernext; 43 _numbernext++; 44 for (int i = 1; i <= n; i++) 45 if (tab[1][i].num[0] == numbernext) 46 _idnow = i; 47 } 48 for (int i = 2; i <= n; i++) 49 if (tab[i][i].num == tab[1][i].num) 50 group.insert(make_pair(tab[i][i].num[0], 0)); 51 for(int i=1;i<=n;i++) 52 for (int j = 1; j <= n; j++) { 53 if (tab[i][j].num != "+") { 54 if (tab[i][j].num.length() == 1) 55 { 56 tab[i][j].val=tab[i][j].val_dec = group[tab[i][j].num[0]]; 57 } 58 else 59 { 60 tab[i][j].val = 10 + group[tab[i][j].num[1]]; 61 tab[i][j].val_dec = group[tab[i][j].num[1]] + n - 1; 62 } 63 } 64 } 65 bool flag = true; 66 for(int i=2;i<=n;i++) 67 for (int j = 2; j <= n; j++) { 68 if (tab[i][j].val_dec != tab[1][i].val_dec + tab[j][1].val_dec) 69 { 70 flag = false; 71 break; 72 } 73 } 74 if (flag) { 75 cout << tab[1][2].num << "=" << group[tab[1][2].num[0]]; 76 for (int i = 3; i <= n; i++) 77 cout << " " << tab[1][i].num << "=" << group[tab[1][i].num[0]]; 78 printf(" %d ", n - 1); 79 } 80 else 81 printf("ERROR! "); 82 return 0; 83 }
好奇特的题,我都不知道咋分类,那就枚举好了|||
思路:
这道题要想清楚几点:
设表为n进制
1)一定有进位
证:若没有进位,则最大数M<n/2
然而此时M+M>M,显然不成立。
可以顺推到结论2)所列数字一定是0~n-1这些数字(通过进位可知)
由2)又进一步推得n为行数-1
3)两位数数字的第一位的字母一定代表数字1(M+M<2*n)