RAID! UVA-509 (奇偶校验)

vjudge链接

原题链接

初学算法,乍一看很复杂,题目很长。但其实关键点就两个词:"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

posted @ 2020-02-04 20:18  桜風の狐  阅读(325)  评论(0编辑  收藏  举报