csp201903-3
#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';
}
};
-truct 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与stdin的同步,从而加快cin的速度
cin >> n >> s >> l;//读入磁盘的数目,条带的大小以及现存磁盘数
int no;//输入的磁盘编号
string data;//输入的字符串
dataLength = -1;//输入的字符串的长度
diskDatas = new DiskData[n];//定义n个磁盘
for (int i = 0; i < n; i++)
diskDatas[i].data = NULL;//首先将n个磁盘的数据置为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()
{
Disks ds;
ds.getData();
ds.output();
return 0;
}