#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct DiskData
{
unsigned char * data;
void analyseStr(string str)
{
data=new unsigned char[str.length()/2];
for(unsigned i=0; i<str.length()/2; i++)
{
data[i]=chartoint(str[i*2])*16+chartoint(str[i*2+1]);
}
}
int chartoint(char d){
if(d>='a'&&d<='f')return d-'a'+10;
if(d>='A'&&d<='F')return d-'A'+10;
return d-'0';
}
};
struct Disks
{
int n,s,l,dataLength;//盘数,条带块数,现存盘数
DiskData *diskDatas;
int blockCount,*blockNo;
void getData();
void fillData(int disk)
{
diskDatas[disk].data=new unsigned char[dataLength];
for(int i=0; i<dataLength; i++)
{
diskDatas[disk].data[i]=0;
for(int j=0; j<n; j++)
{
if(j!=disk)
diskDatas[disk].data[i]^=diskDatas[j].data[i];
}
}
}
void print(int disk,int blk)
{
printf("%02X%02X%02X%02X\n",diskDatas[disk].data[blk*4],
diskDatas[disk].data[blk*4+1],
diskDatas[disk].data[blk*4+2],
diskDatas[disk].data[blk*4+3]);
}
bool check(int disk,int blk){
if(blk*4+4-1>dataLength)//超出范围
return false;
if(n-l>1&&diskDatas[disk].data==NULL)
return false;//无法推算
if(diskDatas[disk].data==NULL)fillData(disk);
return true;
}
void getBolck(int r)
{
int level=r/((n-1)*s); //获取读取的数据层数;
int curp=(n-level%n)-1; //获取读取的数据层数P块所在盘号,逐次左移一块盘
int blk=level*s+r%s; //获取数据所在硬盘的块索引
int disk=r%((n-1)*s)/s+curp+1; //获取读取的数据所在硬盘索引,以curp为基准向右走
disk=disk%n;
if(check(disk,blk))print(disk,blk);
else printf("-\n");
}
void output()
{
for(int i=0; i<blockCount; i++)
getBolck(blockNo[i]);
}
};
void Disks::getData()
{
ios::sync_with_stdio(false);
cin>>n>>s>>l;
int no;
string data;
dataLength=-1;
diskDatas=new DiskData[n];
for(int i=0; i<n; i++)
diskDatas[i].data=NULL;
for(int i=0; i<l; i++)
{
cin>>no>>data;
if(dataLength==-1)dataLength=data.length()/2;
diskDatas[no].analyseStr(data);
}
cin>>blockCount;
blockNo=new int[blockCount];
for(int i=0; i<blockCount; i++)cin>>blockNo[i];
}
int main()
{
//freopen("d:\\csp\\201903-3-2.txt","r",stdin);
Disks ds;
ds.getData();
ds.output();
return 0;
}
以上代码能够通过,但运算时间九百多毫秒,时间消耗主要存在于将接收的字符串分解为字节数组上,尝试调整了一下代码,测试效率200毫秒左右
#include <bits/stdc++.h>
using namespace std;
struct Disks
{
int n,s,l,dataLength;//盘数,条带块数,现存盘数
string *diskDatas;
int blockCount,*blockNo;
void getData();
int h2d(char h){
return h>='0'&&h<='9'?h-'0':h-'A'+10;
}
char d2h(int d){
return d<=9?d+'0':d+'A'-10;
}
void getBolck(int r)
{
int level=r/((n-1)*s); //获取读取的数据层数;
int curp=(n-level%n)-1; //获取读取的数据层数P块所在盘号,逐次左移一块盘
int blk=level*s+r%s; //获取数据所在硬盘的块索引
int disk=curp+1+r/s%(n-1); //获取读取的数据所在硬盘索引,以curp为基准向右走
disk%=n;
string s="-";
if(blk*8+8<=dataLength){
if(!diskDatas[disk].empty()){
s=diskDatas[disk].substr(blk*8,8);
}
else if(n-l==1){
s="00000000";
for(int i=0;i<n;i++){
if(disk==i)continue;
for(int j=0;j<8;j++){
s[j]=d2h(h2d(s[j])^h2d(diskDatas[i][blk*8+j]));
}
}
}
}
cout<<s<<endl;
}
void output()
{
for(int i=0; i<blockCount; i++){
getBolck(blockNo[i]);
}
}
};
void Disks::getData()
{
ios::sync_with_stdio(false);
cin>>n>>s>>l;
int no;
string data;
diskDatas=new string[n];
for(int i=0; i<l; i++)
{
cin>>no;
cin>>diskDatas[no];
}
dataLength=diskDatas[no].length();
cin>>blockCount;
blockNo=new int[blockCount];
for(int i=0; i<blockCount; i++)cin>>blockNo[i];
}
int main()
{
//freopen("d:\\csp\\201903-3-1.txt","r",stdin);
Disks ds;
ds.getData();
ds.output();
return 0;
}