试题编号: | 201903-3 |
试题名称: | 损坏的RAID5 |
时间限制: | 1.0s |
内存限制: | 512.0MB |
问题描述: |
#include<iostream>
#include<math.h>
#include<string.h>
#define N 1005
#define MAXL 89999
using namespace std;
char disk[N][MAXL];
int n,s,l; //硬盘的数目,条带的大小,现存的数目
int char2digit(char c){ //十六进制字符转数字
if(isdigit(c)) return c-'0';
return c-'A'+10;
}
char digit2char(int d){ //数字转十六进制字符
if(d<10) return '0'+d;
return 'A'+d-10;
}
string calcu(string a,string b){//进行两个字符串的异或运算
for(int i=0;i<8;i++){
a[i]=digit2char(char2digit(a[i])^char2digit(b[i]));//每两个字符之间进行异或运算
}
return a;
}
int main(){
int len;
cin>>n>>s>>l;
string str;
getline(cin,str);
for(int i=0;i<l;i++){
int id;
cin>>id;
fgets(disk[id],MAXL,stdin); //对于长字符串,请勿直接使用scanf或cin,否则超时
//注意!!!,这种方式输入char类型数组,适用于特别长的字符串节省时间,
//但其第一个字符为空格,在进行计算的时候注意这一点
len=strlen(disk[id]);
}
int m;cin>>m;//要执行的查找数,要查找的块号
while(m--){
int disk_id,k_id,d,sub_num,index_num;//表示输入的块号所在的
// 磁盘号 磁盘内行号 开始截取字节的位置 在条块内位移的块数
cin>>d;
index_num=d%s;//在条块内位移的块数 用输入块号取余每条的块数
d/=s;//将每个条块看做一个整体
disk_id=d%n;//整个条块所在的磁盘标号
k_id=d/(n-1);//整个条块所在的磁盘内部的行号
sub_num=k_id*s*8;//在该行之前的块数*8就是之前块的字节数
sub_num+=index_num*8;//再加上本条块内的字节位移数,就是要截取字节的起始位置
if((disk[disk_id][0]=='\0' && l<n-1) || sub_num+8>len){
//若磁盘字节为空,并且损坏磁盘的数量多于1个,则不可能推出,或者是要查找的字节数超标
cout<<"-"<<endl;
}else if(disk[disk_id][0]!='\0'){
//若查找的磁盘不为空,则根据位置输出就可以了
for(int c=1;c<=8;c++){
cout<<disk[disk_id][sub_num+c];
}cout<<endl;
}else{
//其余情况需要推算出损坏磁盘的字节
string ans="00000000";
char s[8];
for(int i=0;i<n;i++){//注意s的提取 s[c-1]
for(int c=1;c<=8;c++){
s[c-1]=disk[i][sub_num+c];
}
string temp=(string)s;
if(i!=disk_id)ans=calcu(ans,temp);
}
cout<<ans<<endl;
}
}
}
更多相关CCF的试题解答,请点击>>CCF历年认证考试解答