洛谷P1013 [NOIP1998 提高组] 进制位

P1013 [NOIP1998 提高组] 进制位

P1013题目传送门

这是一道提高+/省选-的蓝题,有亿点点难度,我们先分析一下。

分析

字母的数量等于进制的大小,判错的时候,可以看一下那个表格右下角的一个等腰三角形,就会发现有一个由两位字母组成的三角形。

我们验算一下,对于 \(L\),在该三角形的双位字母中的个位中出现了三次,则

\[4-1-3=0 \]

\(L\) 代表的就是零了,然后依次验算 \(n-1-c\)\(c\) 表示次数,发现都等于实际上的进制数字。

然后我们依旧可以发现,在 \(L\) 这一行里面,没有双位字母出现,所以我们可以给 \(L\)\(0\),就这样依次查下去,就会发现,下一行, \(K\) 有一个双位字母,然后 \(K\)\(1\),等等,依此类推。

我们以上面两条作为判错依据,可以用 map 映射来统计次数,会更加便捷。

AC Code

#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];
    }//第一行
    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;
    return 0;
}
//求通过
posted @ 2023-08-29 09:16  XLoffy  阅读(59)  评论(0编辑  收藏  举报