洛谷P1013 [NOIP1998 提高组] 进制位
P1013 [NOIP1998 提高组] 进制位
这是一道提高+/省选-的蓝题,有亿点点难度,我们先分析一下。
分析
字母的数量等于进制的大小,判错的时候,可以看一下那个表格右下角的一个等腰三角形,就会发现有一个由两位字母组成的三角形。
我们验算一下,对于 \(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;
}
//求通过