P1013 [NOIP1998 提高组] 进制位の题解

· · 题解

P1013 [NOIP1998 提高组] 进制位

1w提交的题目甚至可以写题解!

此题解面向萌新,没有高深的公式,自然不够严谨,大佬请出门左转离开。

题目传送门,和一些更好的体验。

其实就是一个找规律的题目:

首先,在输出样例可以看到不同字母必须代表不同数字的字样,这就代表这每个字母所代表的数字都是不同的数字,自然而然的就知道了进制为 N-1(输入的 N 去掉一个 + 号,其实也就是字母的总数量)。

其次,代表数的关系不好讲,就上一张九九加法表就知道了。

0+0=0 1+0=1 2+0=2 3+0=3 4+0=4 5+0=3 6+0=0 7+0=7 8+0=8 9+0=9
0+1=1 1+1=2 2+1=3 3+1=4 4+1=5 5+1=3 6+1=0 7+1=8 8+1=9 9+1=10
0+2=2 1+2=3 2+2=4 3+2=5 4+2=6 5+2=3 6+2=0 7+2=9 8+2=10 9+2=11
0+3=3 1+3=4 2+3=5 3+3=6 4+3=7 5+3=3 6+3=0 7+3=10 8+3=11 9+3=12
0+4=4 1+4=5 2+4=6 3+4=7 4+4=8 5+4=3 6+4=0 7+4=11 8+4=12 9+4=13
0+5=5 1+5=6 2+5=7 3+5=8 4+5=9 5+5=3 6+5=0 7+5=12 8+5=13 9+5=14
0+6=6 1+6=7 2+6=8 3+6=9 4+6=10 5+6=3 6+6=0 7+6=13 8+6=14 9+6=15
0+7=7 1+7=8 2+7=9 3+7=10 4+7=11 5+7=3 6+7=0 7+7=14 8+7=15 9+7=16
0+8=8 1+8=9 2+8=10 3+8=11 4+8=12 5+8=3 6+8=3 7+8=15 8+8=16 9+8=17
0+9=9 1+8=10 2+8=11 3+9=12 4+9=13 5+9=14 6+9=15 7+9=16 8+9=17 9+9=18

从列看,每一列有几个二位数这个数就是多少,同时自己再想几个验证一下,也能轻易的发现这个规律,所以,只要根据这两个结论就可以得出结果。

判断 ERROR!也简单,先初步判断出来之后再一位一位的判断就可以了,大概伪代码如下:

int c;
if(当前位置是一位数){
    c = 当前位置的字符串第一项的值;
}else{
    c = 当前位置的字符串第一项的值*(n-1)+当前位置的字符串第二项的值;
}
if (c != 当前位置的两个加数和) {
    cout << "ERROR!" << endl; //你愿意话用printf当然可以
    return 0;//结束,免得之后再输出
}

剩下的就都没有任何难度了。

上代码!

AC Code

// 其实下面的p可以和m省略,但是m是后来偷懒写的,就没去合并了
#include <bits/stdc++.h>
using namespace std;
int n;
string s[15][15];
map<char, int> m;
int p[15];

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            cin >> s[i][j];
    for (int i = 2; i <= n; ++i) {
        int sum = 0;
        for (int j = 1; j <= n; ++j)
            if (s[i][j].size() == 2)
                sum++;
        p[i] = sum;
        m.insert({s[i][1][0], sum});
    }
    for (int i = 2; i <= n; ++i) 
        for (int j = 2; j <= n; ++j) {
            int a = p[i];
            int b = p[j];
            int c;
            if (s[i][j].size() == 2)
                c = m[s[i][j][0]] * (n-1) + m[s[i][j][1]];
            else
                c = m[s[i][j][0]];

            if (c != a + b) {
                cout << "ERROR!" << endl;
                return 0;
            }
        }

    for (int i = 2; i <= n; ++i)
        cout << s[i][1] << "=" << p[i] << " ";
    cout << endl << n - 1;
    return 0;
}