【CCF】 损坏的RAID5

7 篇文章 0 订阅





#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#define N 1005
#define MAXL 81925

int n;//阵列中硬盘的数目
int s;//条带的大小(单位:块,1块是4个字节),8个字符
int l;//现存的硬盘数目
int m;//读操作个数
int b;//块编号(第一个为0)
char disk[N][MAXL];
int len;//磁盘内容字符串长度,用来做判断
//磁盘是整个,包括n个硬盘

int six_int(char c){//十六进制字符转为数字
    //学到了新函数hhh
    if(isdigit(c))
        return c-'0';
    else
        return c-'A'+10;
}

char int_six(int d){//数字转十六进制字符
    if(d<10)
        return '0'+d;
    return 'A'+d-10;
}

void calxor(char a[],char b[]){//计算a^b~异或操作啦
    for(int i=0;i<8;i++)
        a[i]=int_six(six_int(a[i])^six_int(b[i]));
}
//字符串的话,最后要有个/0
char* substr(char *s,int n){//返回从s起长度为n的字符串
    char *sp=(char*)malloc(sizeof(char)*(n+1));
    for(int i=0;i<n;i++)
        sp[i]=s[i];
    sp[n]=0;
    return sp;
}

int main(){
    scanf("%d%d%d",&n,&s,&l);//读入磁盘信息
    int index=0;//硬盘序号
    for(int i=0;i<l;i++){
        scanf("%d%*c",&index);
        fgets(disk[index],MAXL,stdin);
    }
    len=strlen(disk[index]);

    //处理请求
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d",&b);
        //这两个式子纯属找规律(笑哭
        int diskId=b%(n*s)/s;
        int lineId=b/((n-1)*s)*s+b%s;
        //阵列不完整,且被读出的块所在的硬盘缺失
        //且该数据无法由现存的硬盘数据推算出来
        if((lineId+1)*8>len||(disk[diskId][0]=='\0'&&l<n-1)){
            //(lineId+1)*8其实就是一个disk的字符长度,意思是块号超过磁盘大小
            printf("-\n");
        }
        else if(disk[diskId][0]!='\0'){//b块所在盘存在
            printf("%s\n",substr(disk[diskId]+lineId*8,8));
        }
        else{//b块所在的盘丢失,但可以还原
            char ans[10]="00000000";
            for(int j=0;j<n;j++){
                if(j!=diskId)
                    calxor(ans,substr(disk[j]+lineId*8,8));
            }
            printf("%s\n",ans);
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值