509 - RAID! (UVA)

文章讲述了作者在解决UVA509问题时,通过参考大神的代码并修改思路,将parityblock和datablock的处理统一,简化了位运算,以提高代码效率。

题目链接如下:

Online Judge

起先写的代码比较复杂,后来参考这位大神【UVA 509 --- RAID!】模拟+位运算_uva509-CSDN博客 的代码修改了思路,代码如下:

(这里关键点就是,parity block和data block其实可以一致处理,不需要区分。)

#include <cstdio>
#include <algorithm>
#include <string>
// #define debug

int d, s, b, kase = 0;
char op[5];
char data[6][100][64];
char line[6410];
bool flag;

int main(){
    #ifdef debug
    freopen("0.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
    #endif
    while(scanf("%d", &d) == 1 && d){
        scanf("%d %d %s", &s, &b, op);
        flag = true;
        for(int i = 0; i < d; ++i){
            scanf("%s", line);
            for(int j = 0; j < b; ++j){
                for(int k = 0; k < s; ++k){
                    data[i][j][k] = line[j * s + k];
                }
            }
        }
        for(int j = 0; j < b; ++j){
            for(int k = 0; k < s; ++k){
                int ix = -1;
                int x = 0;
                for(int i = 0; i < d; ++i){
                    if(data[i][j][k] == 'x'){
                        if(ix != -1){
                            k = s;
                            j = b;
                            flag = false;
                            break;
                        }
                        ix = i;
                    } else{
                        x ^= data[i][j][k] - '0';
                    }
                }
                if(ix == -1){
                    if((op[0] == 'E' ? 0 : 1) != x){
                        flag = false;
                        k = s;
                        j = b;
                        break;
                    }
                } else{
                    data[ix][j][k] = (op[0] == 'E' ^ x) ? '0' : '1';
                }
            }
        }
        if(!flag){
            printf("Disk set %d is invalid.\n", ++kase);
            continue;
        }
        std::string str;
        for(int j = 0; j < b; ++j){
            for(int i = 0; i < d; ++i){
                for(int k = 0; k < s; ++k){
                    if(i != j % d){
                        str.push_back(data[i][j][k]);
                    }
                }
            }
        }
        while(str.size() % 4){
            str.push_back('0');
        }
        printf("Disk set %d is valid, contents are: ", ++kase);
        for(int i = 0; i < str.size() / 4; ++i){
            int tmp = ((str[4 * i] - '0') << 3) + ((str[4 * i + 1] - '0') << 2) + ((str[4 * i + 2] - '0') << 1) + str[4 * i + 3] - '0';
            printf("%X", tmp);
        }
        printf("\n");
    }
    #ifdef debug
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}

原先的代码如下(也能AC,但思路比较繁琐):

#include <cstdio>
#include <algorithm>
#include <string>
// #define debug

int d, s, b, cnt, pivot, kase = 0;
char op[5];
char data[6][100][64];
char line[6410];
int missing[6410];
bool flag;
char table[] = "0123456789ABCDEF";

int main(){
    #ifdef debug
    freopen("0.txt", "r", stdin);
    freopen("1.txt", "w", stdout);
    #endif
    while(scanf("%d", &d) == 1 && d){
        scanf("%d %d %s", &s, &b, op);
        std::fill(missing, missing + s * b, 0);
        flag = true;
        for(int i = 0; i < d; ++i){
            scanf("%s", line);
            for(int j = 0; j < b; ++j){
                for(int k = 0; k < s; ++k){
                    data[i][j][k] = line[j * s + k];
                    if(line[j * s + k] == 'x'){
                        missing[j * s + k]++;
                        if(flag && missing[j * s + k] > 1){
                            flag = false;
                        }
                    }
                }
            }
        }
        if(!flag){
            printf("Disk set %d is invalid.\n", ++kase);
            continue;
        }
        for(int j = 0; j < b; ++j){
            for(int k = 0; k < s; ++k){
                cnt = 0;
                for(int i = 0; i < d; ++i){
                    if(i == j % d){
                        continue;
                    }
                    if(data[i][j][k] == '1'){
                        cnt++;
                    } else if(data[i][j][k] == 'x'){
                        pivot = i;
                    }
                }
                cnt %= 2;
                if(missing[j * s + k] == 0 || data[j % d][j][k] == 'x'){
                    if((op[0] == 'E' && cnt) || (op[0] == 'O' && !cnt)){
                        if(data[j % d][j][k] == 'x'){
                            data[j % d][j][k] = '1';
                        } else if(data[j % d][j][k] == '0'){
                            flag = false;
                            j = b;
                            break;
                        }
                    } else{
                        if(data[j % d][j][k] == 'x'){
                            data[j % d][j][k] = '0';
                        } else if(data[j % d][j][k] == '1'){
                            flag = false;
                            j = b;
                            break;
                        }
                    }
                } else{
                    if((op[0] == 'E' && !cnt && data[j % d][j][k] == '0') || (op[0] == 'E' && cnt && data[j % d][j][k] == '1')
                        || (op[0] == 'O' && !cnt && data[j % d][j][k] == '1') || (op[0] == 'O' && cnt && data[j % d][j][k] == '0')){
                            data[pivot][j][k] = '0';
                    } else{
                        data[pivot][j][k] = '1';
                    }
                }
            }
        }
        if(!flag){
            printf("Disk set %d is invalid.\n", ++kase);
            continue;
        }
        printf("Disk set %d is valid, contents are: ", ++kase);
        std::string str;
        for(int j = 0; j < b; ++j){
            for(int i = 0; i < d; ++i){
                for(int k = 0; k < s; ++k){
                    if(i != j % d){
                        str.push_back(data[i][j][k]);
                    }
                }
            }
        }
        while(str.size() % 4){
            str.push_back('0');
        }
        for(int i = 0; i < str.size() / 4; ++i){
            int tmp = 8 * (str[4 * i] - '0') + 4 * (str[4 * i + 1] - '0') + 2 * (str[4 * i + 2] - '0') + str[4 * i + 3] - '0';
            printf("%c", table[tmp]);
        }
        printf("\n");
    }
    #ifdef debug
    fclose(stdin);
    fclose(stdout);
    #endif
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值