题目有点长,看了几遍都不清楚奇校验和偶校验,后来一翻紫书,整个就全知道了。
奇校验就是指异或之后都为1,偶校验是指异或之后都为0,这样就好做了嘛,直接暴力好了
一开始打算用unsigned long long的,然后发现有x就放弃了,就全都用了字符串
最后处理4位一读也想不到好办法,也就暴力了。
#include <cstdio>
using namespace std;
int d,s,b,kcase=1;
char c,str[6][6500];
bool judge(int k),success=true;
void getans();
int main(){
while(scanf("%d",&d)&&d){
scanf("%d%d%*c%c",&s,&b,&c);
for(int i=0;i<d;++i){
scanf("%s",str[i]);
for(int j=b*s-1;j>=0;--j)
if(str[i][j]!='x')
str[i][j]-='0';
}
for(int i=0;i<b;++i)
if(!judge(i)){
printf("Disk set %d is invalid.\n",kcase++);
success=false;
break;
}
if(success)
printf("Disk set %d is valid, contents are: ",kcase++),getans();
success=true;
}
return 0;
}
bool judge(int k){
bool hasx=false;
int x;
char ch;
for(int i=k*s,j;i<(k+1)*s;++i,hasx=false){
for(j=0,ch=0;j<d;++j)
if(str[j][i]=='x'&&hasx)
return false;
else if(str[j][i]=='x')
hasx=true,x=j;
else
ch=(str[j][i]^ch);
if(!hasx&&ch!=(c=='O'))
return false;
else if(hasx)
str[x][i]=(c=='O')^(ch);
}
return true;
}
void getans(){
int digits=3,te=0;
for(int i=0,k=i%d;i<b;k=++i%d)
for(int j=0;j<d;++j)
if(j!=k){
for(int m=0;m<s;++m){
te|=(str[j][i*s+m]<<digits);
if(!digits){
printf("%X",te);
digits=3;
te=0;
}
else
--digits;
}
}
if(digits!=3)
printf("%X",te);
printf("\n");
}