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;
}


posted @ 2015-02-01 15:47  Popco  阅读(386)  评论(0编辑  收藏  举报