点击打开题目链接
给出数据块,判断合法性,合法则恢复并输出完整的数据。非法则报告磁盘非法。
合法:
1.任意一列如果没有x则应该满足奇校检或偶校检条件(即1的个数为奇数或者偶数)。
2.某一列如果有x,只允许有一个。
代码:
#include<bits/stdc++.h>
using namespace std;
char mp[8][8000];
int d, s, b;
char c;
int op;
int input() {
cin >> d;
memset(mp, 0, sizeof(mp));
if(d == 0) return 0;
cin >> s >> b;
cin >> c;
op = (c == 'E') ? 0 : 1;
for(int i = 0; i < d; i++)
scanf("%s", mp[i]);
return 1;
}
int isLegal() {
for(int i = 0; i < s * b; i++) {
int tag = 0, numx = d, cntx = 0;
for(int j = 0; j < d; j++) {
if(mp[j][i] == 'x') {
if(cntx == 0) {
cntx++;
numx = j;
}
else return 0;
}
else {
if(j == 0) tag = mp[j][i] - '0';
else tag ^= (mp[j][i] - '0');
}
}
if(cntx == 0 && tag != op) return 0;
else mp[numx][i] = (tag ^ op) + '0';
}
return 1;
}
void recover() {
string str = "";
for(int i = 0; i < b; i++) {
for(int j = 0; j < d; j++) {
if(j == i % d) continue;
for(int k = i * s; k < (i + 1) * s; k++) {
str += mp[j][k];
}
}
}
int tag = 0;
while(str.length() % 4) str += '0';
for(int i = 0; i < str.length(); i += 4) {
int t = 0;
for(int j = 0; j < 4; j++) {
t *= 2;
if(str[i+j] != '0') {
t += (str[i+j] - '0');
}
}
printf("%X", t);
}
cout << endl;
}
int main() {
//freopen("D:\\input.txt", "r", stdin);
//freopen("D:\\output.txt", "w", stdout);
//ios::sync_with_stdio(false);
int kase = 0;
while(input()) {
if(!isLegal())
printf("Disk set %d is invalid.\n",++kase);
else{
printf("Disk set %d is valid, contents are: ",++kase);
recover();
}
}
return 0;
}