UVA - 509 RAID!(模拟 + 异或)

35 篇文章 0 订阅
11 篇文章 0 订阅

点击打开题目链接
给出数据块,判断合法性,合法则恢复并输出完整的数据。非法则报告磁盘非法。
合法:
1.任意一列如果没有x则应该满足奇校检或偶校检条件(即1的个数为奇数或者偶数)。
2.某一列如果有x,只允许有一个。
代码:

#include<bits/stdc++.h>

using namespace std;
char mp[8][8000];
int d, s, b;
char c;
int op;

int input() {
    cin >> d;
    memset(mp, 0, sizeof(mp));
    if(d == 0) return 0;
    cin >> s >> b;
    cin >> c;
    op = (c == 'E') ? 0 : 1;
    for(int i = 0; i < d; i++)
        scanf("%s", mp[i]);
    return 1;
}

int isLegal() {
    for(int i = 0; i < s * b; i++) {
        int tag = 0, numx = d, cntx = 0;
        for(int j = 0; j < d; j++) {
            if(mp[j][i] == 'x') {
                if(cntx == 0) {
                    cntx++;
                    numx = j;
                }
                else return 0;
            }
            else {
                if(j == 0) tag = mp[j][i] - '0';
                else tag ^= (mp[j][i] - '0');
            }
        }
        if(cntx == 0 && tag != op) return 0;
        else mp[numx][i] = (tag ^ op) + '0';
    }
    return 1;
}

void recover() {
    string str = "";
    for(int i = 0; i < b; i++) {
        for(int j = 0; j < d; j++) {
            if(j == i % d) continue;
            for(int k = i * s; k < (i + 1) * s; k++) {
                str += mp[j][k];
            }
        }
    }
    int tag = 0;
    while(str.length() % 4) str += '0';
    for(int i = 0; i < str.length(); i += 4) {
        int t = 0;
        for(int j = 0; j < 4; j++) {
            t *= 2;
            if(str[i+j] != '0') {
                t += (str[i+j] - '0');
            }
        }
        printf("%X", t);
    }
    cout << endl;
}

int main() {
    //freopen("D:\\input.txt", "r", stdin);
    //freopen("D:\\output.txt", "w", stdout);
    //ios::sync_with_stdio(false);
    int kase = 0;
    while(input()) {
        if(!isLegal())
            printf("Disk set %d is invalid.\n",++kase);
        else{
            printf("Disk set %d is valid, contents are: ",++kase);
            recover();
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chook_lxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值