UVa 509 - RAID! <位运算练习>
今天看到一位学长写的博客,很受启发。要抛却功利心,形成自己的思维,不要老看题解,要追求多种方法,要优化自己的程序直到不能再优化,关注自己程序的运行时间和内存占用的排名。还有写题解不能只写两三句话就完事,要不然还不如不写。
这道RAID的题目,首先是位运算,实际上我的思路是看样例猜出来的,奇校验所有数字加起来为奇数,偶校验所有数字加起来为偶数,后来查阅资料:偶校验中当实际数据中“1”的个数为偶数的时候,这个校验位就是“0”,否则这个校验位就是“1”,奇校验正好相反,可知自己的猜想是正确的。
然后还有一点是输出数据的时候,4个bit转化为一个十六进制。刚开始做题认为每个数据块输出一个整数,这需要2^(5*64)这么大的数来存储,难道要用大整数类?后来一想,可以每一个十六进制位输出一次便可。
#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; }