RAID! UVA-509 (奇偶校验)
初学算法,乍一看很复杂,题目很长。但其实关键点就两个词:"even parity",偶校验,即所有数据之和为偶数时校验位为 0 ,反之为 1 ;"odd parity",奇校验与之相反。当然也可以用异或 ^ 计算。
输入也不是按照表格中的格式输入,而是每行输入了每个磁盘的所有数据。
还有一句话很重要:"If necessary, add extra ‘0’ bits at the end of the recovered data so the number of bits is always a multiple of 4."
当然少了那句都根本无法过样例。
由于我将数据存在字符数组中,故没有使用异或。
/*
*lang C++ 5.3.0
*user Weilin_C
*/
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
using namespace std;
int main()
{
int isize, idisk, iblock, setn=0;
char parity;
char disks[10][6500];
while (scanf("%d%d%d", &idisk, &isize, &iblock) && idisk) {
setn++;
getchar();
parity=getchar();
//memset(disks, 0, sizeof(disks));
for (int i=0; i<idisk; i++) scanf("%s", disks[i]);
int flag=1; //验证校验位并将校验位置为 space
for (int i=0; i<iblock && flag; i++) {
for (int j=0; j<isize && flag; j++) {
char ans=disks[i%idisk][i*isize+j];
int invalid=0, sta=0, ipos;
if (parity=='O') if (ans=='0') ans='1'; else if (ans=='1') ans='0';
for (int k=0; k<idisk; k++)
if (k==i%idisk) continue;
else if (isdigit(disks[k][i*isize+j])) sta+=disks[k][i*isize+j]-'0';
else {invalid++; ipos=k;}
if (ans=='x') invalid++;
if (invalid>1) flag=0;
else if (invalid==1 && ans!='x') {if (ans-'0'==sta%2) disks[ipos][i*isize+j]='0'; else disks[ipos][i*isize+j]='1';}
else if (ans!='x' && ans-'0'!=sta%2) flag=0;
disks[i%idisk][i*isize+j]=' ';
}
}
if (flag) {
printf("Disk set %d is valid, contents are: ", setn);
int ans=0, n=0;
for (int i=0; i<iblock; i++) {
for (int j=0; j<idisk; j++) {
for (int k=0; k<isize; k++) {
if (isdigit(disks[j][i*isize+k])) {ans*=2; ans+=disks[j][i*isize+k]-'0'; n++;}
if (n==4) {printf("%X", ans); n=ans=0;}
}
}
}
while (n!=0 && n!=4) {ans*=2; n++;}
if (n>0) printf("%X", ans);
putchar('\n');
} else printf("Disk set %d is invalid.\n", setn);
}
return 0;
}
测试样例:
/* sample input */
5 2 5
E
0001011111
0110111011
1011011111
1110101100
0010010111
3 2 5
E
0001111111
0111111011
xx11011111
3 5 1
O
11111
11xxx
x1111
5 2 5
O
1101011111
0101111011
1011101111
1110100000
0010010101
5 2 5
O
1101011111
0101111011
1011101111
1110100000
001001010x
5 2 5
O
x10x0111x1
01x1111011
1x111xx111
1110100x00
0010x1010x
5 2 5
O
110101111x
01x1111011
101110x111
1110100000
0010x1010x
0
/* sample output */
Disk set 1 is valid, contents are: 6C7A79EDFC
Disk set 2 is invalid.
Disk set 3 is valid, contents are: FFC
Disk set 4 is invalid.
Disk set 5 is valid, contents are: 6C7A79EDFC
Disk set 6 is valid, contents are: 6C7A79EDFC
Disk set 7 is invalid.
by SDUST weilinfox
原文链接:https://www.cnblogs.com/weilinfox/p/12260952.html