CCF 201903-3损坏的RAID5 90分(详细注释)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题记
这道题依然是考阅读理解(无奈)
关键点在于找出来查找的b在哪个硬盘上,并且在这个硬盘的第几块,好好理解一下题意其实公式都是细心推可以推出来的,因为代码里有很多注释,这里就不再赘述了。

#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;

const string base="0123456789ABCDEF";
const int Maxn=1e3+10;

//输入
int n,s,l;//硬盘数目、每个条带的块数、现存的硬盘数
int m,b;//查询的次数、查询的块的编号

string D[Maxn];

int value(char c){
    if(c>='0'&&c<='9')
        return c-'0';
    else
        return c-'A'+10;
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>s>>l;
    int id;
    int length=0;//记录每个硬盘存储的条带数
    for(int i=0;i<l;i++){
        cin>>id;
        cin>>D[id];
        if(length==0)
            length=D[id].size()/8/s;
    }
    cin>>m;
    for(int i=0;i<m;i++){
        cin>>b;
        //查询点所在的条带的行号(以下行皆为以条带分出来的行而不是块)
        int striperow=b/s/(n-1);
        //和b在同一行的检验条带所在的列(硬盘编号)
        int colp=n-1-striperow%n;
        //b是在第(b/s+1)个条带中,减去(n-1)*striperow(b所在条带之前行的条带总数)
        //就能得到b当前所在条带是本行第几个条带,再对n求余就得到该条带是在哪个硬盘中
        int colb=(colp+(b/s+1-(n-1)*striperow))%n;
        //b在colb号硬盘的blk号块
        int blk=striperow*s+b%s;
        //查的b硬盘中根本没有(超过最大块编号)或者缺的硬盘数大于1那么就无法推算出来
        if(striperow>=length||(n-l)>=2)
            cout<<"-"<<endl;
        //要查询的b所在的那一块硬盘没有缺失可以直接读取
        else if(D[colb].size()!=0){
            cout<<D[colb].substr(blk*8,8)<<endl;
        }
        //要查询的b所在的那一块硬盘缺失了
        else if(D[colb].size()==0){
            string ans="00000000";
            //对每一块已知的其余硬盘相应的位置进行异或运算
            for(int i=0;i<n;i++){
                if(i!=colb){
                    //获取对应的块的字符串
                    string temp=D[i].substr(blk*8,8);
                    for(int j=0;j<8;j++)
                        ans[j]=base[value(ans[j])^value(temp[j])];
                }
            }
            cout<<ans<<endl;
        }

    }
    return 0;
}

样例输入1

2 1 2
0 000102030405060710111213141516172021222324252627
1 000102030405060710111213141516172021222324252627
2
0
1

样例输入2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值