1.解题思路
这道题太抽象了,一开始都没太搞懂在讲啥。。。解决该题需要了解条带、磁盘号的定义。
下图以样例2,输入编号为5的块为例:
请务必加上ios::sync_with_stdio(false),否则会超时只有30分
2.满分代码
#include<iostream>
using namespace std;
const int N=1e3+1;
string d[N];
int n,s,l,m;
const string a="0123456789ABCDEF";
int tran(char c)//将字符转为数字
{
if(c>='0'&&c<='9')return c-'0';
else
return c-'A'+10;
}
void cal(string &res,string x)//计算两个十六进制字符串异或的结果
{
for(int i=0;i<8;i++)
{
int y1=tran(res[i]);
int y2=tran(x[i]);
res[i]=a[y1^y2];
}
}
string Xor(int dnode,int bnode)//恢复
{
string res(8,'0');
for(int i=0;i<=n;i++)
{
if(i!=dnode)
{
string x=d[i].substr(bnode,8);
cal(res,x);
}
}
return res;
}
int main()
{
ios::sync_with_stdio(false);//务必要加 否则超时只能30
cin>>n>>s>>l;
n--;
int maxline=0;
for(int i=1;i<=l;i++)
{
int x;
cin>>x;
cin>>d[x];
maxline=(d[x].size()/8)/s;//一块4字节 一字节两字符 所以一块8字符
}
cin>>m;
while(m--)
{
int x;
cin>>x;
int snode=x/s;//条带数
int lnode=snode/n;//行数
int dnode=(n-lnode%(n+1)+snode%n+1)%(n+1);//编号为x的块所在磁盘块数
int len=d[dnode].size();
if(lnode>=maxline)cout<<"-"<<endl;//超过最大行数
else if(len)//内容未缺失
{
int bnode=8*(x%s+lnode*s);//编号为x的块在其磁盘上的 bnode 位置处
cout<<d[dnode].substr(bnode,8)<<endl;
}
else if(!len&&l==n)//内容缺失且块数足够恢复
{
int bnode=8*(x%s+lnode*s);
cout<<Xor(dnode,bnode)<<endl;
}
else
cout<<"-"<<endl;
}
return 0;
}