进制位(NOIP1998)
原创
©著作权归作者所有:来自51CTO博客作者Java大神的原创作品,请联系作者获取转载授权,否则将追究法律责任
传送门
这道题,怎么说呢
说是搜索,我觉得不像,更像乱搞。
那么,我们就说一下乱搞的思路。
首先在读入的时候,我们需要确定两个数字,那就是0和1.
怎么确定?
0很好确定,每一位运算后都不变,那么这个数字就是0.
那么1呢?
我们只要有一个双位数,那么它的十位就是1.
接下来,找到1所在的那一行,有了0和1,就可以推出其他的数字。
最后,在顺着表判断每个格子对不对。
最后输出。
其中,在中途,如果出现非预期情况,那就有问题,直接输出ERROR!即可。
代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
char c[11][11][5];
int ans[30];
char fans[30];
char next[30];
int main(){
memset(c,0,sizeof(c));
memset(ans,-1,sizeof(ans));
memset(fans,0,sizeof(fans));
memset(next,0,sizeof(next));
// printf("%d",c[0][0][1]);
scanf("%d",&n);
for(int i=0;i<n;i++){
int flag=1;
for(int j=0;j<n;j++){
scanf("%s",c[i][j]);
if(j>=1&&c[i][j][0]!=c[0][j][0]){
flag=0;
}
if(c[i][j][1]!=0){
ans[c[i][j][0]-'A']=1;
fans[1]=c[i][j][0];
}
}
if(i==0){
flag=0;
}
if(flag){
ans[c[i][0][0]-'A']=0;
fans[0]=c[i][0][0];
}
}
// printf("\n%c\n",fans[0]);
for(int i=1;i<n;i++){
if(c[i][0][0]==fans[1]){
for(int j=1;j<n;j++){
if(next[c[0][j][0]-'A']==0){
if(c[i][j][1]==0){
next[c[0][j][0]-'A']=c[i][j][0];
}
}else{
printf("ERROR!");
return 0;
}
}
break;
}
}
for(char i=fans[1];ans[i-'A']+1<n-1;i=next[i-'A']){
ans[next[i-'A']-'A']=ans[i-'A']+1;
fans[ans[i-'A']+1]=next[i-'A'];
}
for(int i=1;i<n;i++){
for(int j=1;j<n;j++){
int m=ans[c[i][0][0]-'A']+ans[c[0][j][0]-'A'];
if(m<n-1){
if(fans[m]!=c[i][j][0]){
printf("ERROR!");
return 0;
}
}else{
if(c[i][j][0]!=fans[1]||c[i][j][1]!=fans[m-n+1]){
printf("ERROR!");
return 0;
}
}
}
}
for(int i=1;i<n;i++){
printf("%c=%d",c[i][0][0],ans[c[i][0][0]-'A']);
if(i==n-1){
printf("\n");
}else{
printf(" ");
}
}
printf("%d",n-1);
return 0;
}