18.08.01 luogu 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=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同学为本题新加一组数据

输入输出格式

输入格式:

 

n(n≤9)(n9) 表示行数。

以下 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
 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("\n%d\n", n - 1);
79     }
80     else
81         printf("ERROR!\n");
82     return 0;
83 }
View Code

好奇特的题,我都不知道咋分类,那就枚举好了|||

思路

这道题要想清楚几点:

设表为n进制

1)一定有进位

证:若没有进位,则最大数M<n/2

然而此时M+M>M,显然不成立。

可以顺推到结论2)所列数字一定是0~n-1这些数字(通过进位可知)

由2)又进一步推得n为行数-1

3)两位数数字的第一位的字母一定代表数字1(M+M<2*n)

posted @ 2018-08-01 16:02  TobicYAL  阅读(201)  评论(0编辑  收藏  举报