#include<bits/stdc++.h>
using namespace std;
int d, s, b, kase=0;
char type;
char tab[8][8000];
bool Fix(){
for(int i=0;i<s*b;++i){
int sum=0,cnt=0,x_no;
for(int j=0;j<d;++j){
if(tab[j][i]=='1') ++sum;
if(tab[j][i]=='x') ++cnt,x_no=j;
}
sum%=2;
if(cnt>=2) return false;
else if(cnt == 1){
if(sum)
if(type=='E') tab[x_no][i]='1';
else tab[x_no][i]='0';
else
if(type=='E') tab[x_no][i]='0';
else tab[x_no][i]='1';
}
else if(cnt == 0){
if(type == 'E'&& sum == 1) return false;
if(type == 'O' && sum == 0) return false;
}
}
return true;
}
void out_data()
{
int sum=0,bit_cnt=0;
for(int i=0;i<b;++i){
int except =i%d;
for(int j=0;j<d;j++){
if(j==except) continue;
for(int k=i*s;k<i*s+s;++k){
bit_cnt=(bit_cnt+1)%4;
if(tab[j][k]=='0') sum*=2;
else sum=sum*2+1;
if(!bit_cnt){
printf("%X",sum);
sum=0;
}
}
}
}
if(bit_cnt){
int over =4-bit_cnt;
sum=sum*(1<<over);
printf("%X",sum);
}
printf("\n");
}
int main()
{
ios::sync_with_stdio(false);
while(memset(tab,0,sizeof(tab)),cin>>d&&d){
cin>>s>>b>>type;
for(int i=0;i<d;++i)
cin>>tab[i];
if(!Fix())
printf("Disk set %d is invalid.\n",++kase);
else{
printf("Disk set %d is valid, contents are: ",++kase);
out_data();
}
}
return 0;
}
今天看到一位学长写的博客,很受启发。要抛却功利心,形成自己的思维,不要老看题解,要追求多种方法,要优化自己的程序直到不能再优化,关注自己程序的运行时间和内存占用的排名。还有写题解不能只写两三句话就完事,要不然还不如不写。
这道RAID的题目,首先是位运算,实际上我的思路是看样例猜出来的,奇校验所有数字加起来为奇数,偶校验所有数字加起来为偶数,后来查阅资料:偶校验中当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”,奇校验正好相反,可知自己的猜想是正确的。
然后还有一点是输出数据的时候,4个bit转化为一个十六进制。刚开始做题认为每个数据块输出一个整数,这需要2^(5*64)这么大的数来存储,难道要用大整数类?后来一想,可以每一个十六进制位输出一次便可