UVa 509 - RAID!(读题+位运算)

给出数据块,判断能否恢复数据且是否合法。

好久前跳过去的一道题,找了个英语大神翻译之后总算看懂了……读懂题之后其实并不难,就是简单的数据处理。

一开始没注意到样例2的数据校验不合法,导致浪费了好多时间。修复完成后输出时注意校验块不要算在原始数据里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=6500;
int d,s,b,n;
char data[7][maxn];
bool parity;
bool read(){
scanf("%d%d%d\n",&d,&s,&b);
if(!d) return false;
memset(data,0,sizeof(data));
parity=getchar()=='O',n=s*b;
for(int i=0;i<d;++i)
scanf("%s",data[i]);
return true;
}
bool solve(){
for(int i;i<n;++i){
bool k=false;
int broke=-1;
for(int j=0;j<d;++j){
char& c=data[j][i];
if(c=='1') k=!k;
if(c=='x'){
if(broke!=-1) return false;
else broke=j;
}
}
if(broke==-1&&k!=parity) return false;//校验不合法。
if(broke!=-1) data[broke][i]=k==parity?'0':'1';//修复。
}
return true;
}
void print_ans(bool v){
if(!v) {printf("invalid.\n");return;}
printf("valid, contents are: ");
int num=0,cnt=0;
for(int i=0;i<b;++i){
int pos=i*s;
for(int j=0;j<d;++j){
if(i%d==j) continue;//校验块跳过。
for(int k=0;k<s;++k){
num<<=1,num+=data[j][pos+k]=='1',++cnt;
if((cnt%=4)==0) printf("%X",num),num=0;
}
}
}
if(cnt) printf("%X",num<<(4-cnt));//补0。
printf("\n");
return;
}
int main(){
int t=0;
while(read()){
printf("Disk set %d is ",++t);
print_ans(solve());
}
return 0;
}

** 本文迁移自我的CSDN博客,格式可能有所偏差。 **