uva 509 RAID!

题目:RAID!


题意:
这个题主要是将计算机中的RAID存储方法。
数据由多个磁盘存储,每一行数据都会有一个磁盘空出来,将数据备份。
校验方法分为奇校验和偶校验两种。奇校验是指同一行数据进行异或运算后的结果为1;偶校验值已获得结果为0。
数据中会存在一些数据丢失的情况,要求判断数据是否合法。如果合法,将存储的数据用16进制输出。


思路:
1、将数据拆分成题目要求的形式,每一个位置的数据用字符串存储。
2、判断是否合法。
3、转化成16进制数出。


注意:
1、奇校验是odd parity,偶校验是even parity,第一次读题是理解反了。
2、判断是否合法有两种情况:(1)x的值无法算出; (2)已知数据异或得的值不符合奇偶校验的规则。  第二种情况容易漏掉。
3、题目中的图,磁盘是横着放的;而数据中,磁盘时竖着放的。

4、转化为16进制时,实在末尾补0而不是在开头。



代码:

#include<cstdio>
#include<iostream>
#include<string>
#include<map>
#include<cstring>
#include<vector>
using namespace std;

int n,m,t;
bool parity;
string disk[10][110];
bool Store[10][110];

void init() {
	memset(Store,false,sizeof(Store));
	int j=-1;
	for(int i=0; i<m; i++) {
		j++;
		if(j>=n) j=0;
		Store[j][i]=true;
	}
	return ;
}

map<string,string> mp;
void make_map() {
	mp["0000"]="0";
	mp["0001"]="1";
	mp["0010"]="2";
	mp["0011"]="3";
	mp["0100"]="4";
	mp["0101"]="5";
	mp["0110"]="6";
	mp["0111"]="7";
	mp["1000"]="8";
	mp["1001"]="9";
	mp["1010"]="A";
	mp["1011"]="B";
	mp["1100"]="C";
	mp["1101"]="D";
	mp["1110"]="E";
	mp["1111"]="F";
}

string bin_ox(string x) {
	bool add=x.size()%4;
	if(add!=0)
		for(int i=add; i<4; i++) {
			x=x+"0";
		}

	string Change;
	for(int i=0; i<x.size(); i+=4) {
		string a=x.substr(i,4);
		Change+=mp[a];
	}
	return Change;
}

int main() {
	
	int T=0;
	make_map();
	while(cin>>n&&n!=0) {
		cin>>t>>m;
		++T;
		string EorO;
		cin>>EorO;
		if(EorO=="E") parity=0;
		else parity=1;
		string a[10];
		for(int i=0; i<n; i++) {
			cin>>a[i];
		}

		for(int i=0; i<n; i++) {
			int k=0;
			for(int j=0; j<m*t; j+=t) {
				disk[i][k]=a[i].substr(j,t);
				k++;
			}
		}

		init();

		bool flag=false;
		for(int j=0; j<m; j++) {
			for(int k=0; k<t; k++) {
				vector<int> vec;
				for(int i=0; i<n; i++) {
					if(disk[i][j][k]=='x') {
						vec.push_back(i);
					}
				}
				if(vec.size()>1) {
					flag=true;
					break;
				}
				if(vec.size()==0) continue;
				int x=vec[0];
				bool sum=0;
				for(int i=0; i<n; i++) {
					if(i!=x) {
						sum^=((disk[i][j][k]-'0')%2);
					}
				}
				if(sum==parity) disk[x][j][k]='0';
				else disk[x][j][k]='1';
			}
			if(flag==true) break;
		}

		for(int j=0; j<m; j++) {
			for(int k=0; k<t; k++) {
				bool sum=disk[0][j][k]-'0';
				for(int i=1; i<n; i++) {
					sum^=((disk[i][j][k]-'0')%2);
				}
				if(sum!=parity) {
					flag=true;
					break;
				}
			}
			if(flag==true) break;
		}

		if(flag==true) {
			printf("Disk set %d is invalid.\n",T);
			continue;
		}

		printf("Disk set %d is valid, contents are: ",T);
		string x;
		for(int j=0; j<m; j++) {
			for(int i=0; i<n; i++) {
				if(!Store[i][j])
					x+=disk[i][j];
			}
		}
		cout<<bin_ox(x)<<endl;
	}

	return 0;
}


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值