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';elsereturn 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;}elsecout<<"-"<<endl;}return 0;
}