题目来源于CCF CSP认证系统
思路分析
题目比较难读懂,但是解题思路简单。
要确定所给块的位于哪一个条带上与位于哪一个硬盘上。
!!!(下列中的硬盘数为阵列中的硬盘数)
条带上序号计算:(需要查找的块号)/ 每个条带的大小(块数)/ 硬盘数(减一)
冗余带位置计算(位于哪一个硬盘上): 硬盘数 - 条带数 % 硬盘数 - 1
;
需要查找的块号所在硬盘序号计算: (冗余带所在硬盘序号 + 1 + ( 需要查找的块号 - 条带号 * (硬盘数 - 1 ) * 每个条带大小(块数)) / 每个条带大小(块数)) % 硬盘数
;
需要查找的块号所在硬盘上的字节开始序号:(需要查找的块号 % 每个条带大小(块数) + 条带数 * 条带大小) * 8;
代码解析
#include<iostream>
#include<string>
using namespace std;
const string base = "0123456789ABCDEF";
string str[1007]; //存每一个硬盘的字符串
string X_OR(int start_disk, int label, int n) {
string temp = "00000000";
for (int i = 0; i < n; ++i) {
if (i == start_disk)
continue;
string tp = str[i].substr(label, 8); //截取一个块的长度
for (int j = 0; j < tp.size(); ++j) {
int x = (temp[j] >= '0' && temp[j] <= '9') ? temp[j] - '0' : temp[j] - 'A' + 10;
int y = (tp[j] >= '0' && tp[j] <= '9') ? tp[j] - '0' : tp[j] - 'A' + 10;
temp[j] = base[(x ^ y)];
}
}
return temp;
}
int main()
{
ios::sync_with_stdio(false);
int n, s, l, cnt, max_k = 0;//硬盘数目,条带大小,现存硬盘数
cin >> n >> s >> l;
for (int i = 0; i < l; ++i) {
cin >> cnt; //第几个硬盘
cin >> str[cnt]; //字符串
max_k = str[cnt].size() / 8 / s; // 长度
}
int m, b; //操作数
cin >> m;
while (m--) {
cin >> b; //块号
int tiaodai = b / s / (n - 1); //条带号
int p = n - tiaodai % n - 1; //冗余带的位置 (第几个硬盘)
int start_disk = (p + 1 + (b - tiaodai * (n - 1) * s) / s) % n;
int label = (b % s + tiaodai * s) * 8; //数据开始的字节序好
if (tiaodai >= max_k || (str[start_disk].size() == 0 && n - l >= 2)) //非法长度
cout << "-" << endl;
else if (str[start_disk].size()) {
//存在该硬盘
cout << str[start_disk].substr(label, 8);
cout << endl;
}
else{
//不存在该硬盘,但可以推算出结果
cout << X_OR(start_disk, label, n);
cout << endl;
}
}
return 0;
}
测试结果