CCF CSP2019.3 损坏的RAID5

题目来源于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;
}

测试结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/107503123
今日推荐