题记
这道题依然是考阅读理解(无奈)
关键点在于找出来查找的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