【CSP-201903】损坏的RAID-5

给一个RAID5的模型,直接模拟就好。如果要读取的数据所在硬盘没坏就直接读;如果坏了并且只有这一块硬盘是坏的,那就可以通过异或计算出数据;否则就没法读了。

难点大概就是专业词汇太多,读起来太吃力了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <vector>
using namespace std;
int n, s, l, broken;
vector<string> dt;
vector<bool> working;
string get_block(int disk, int band, int block)
{
return dt[disk].substr((band * s + block) * 8, 8);
}
int xtoi(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else
return c - 'A' + 10;
}
char itox(int x)
{
if (x < 10)
return x + '0';
else
return x - 10 + 'A';
}
void xor_string(string &a, const string &b)
{
for (int i = 0; i < a.size(); i++)
a[i] = itox(xtoi(a[i]) ^ xtoi(b[i]));
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> s >> l;
dt.resize(n);
working.resize(n);
broken = n - l;

for (int i = 0; i < l; i++)
{
int a;
cin >> a;
cin >> dt[a];
working[a] = true;
}

int m;
cin >> m;
while (m--)
{
int vblock; // 虚拟块编号
cin >> vblock;
int pos = vblock % s; // 该块在所属条带的位置
int vband = vblock / s; // 虚拟条带编号
int band = vband / (n - 1); // 真实条带编号
int d = vblock % (n * s) / s; // 数据块所在磁盘编号

try
{
if (working[d]) // 数据所在硬盘没坏
cout << get_block(d, band, pos) << endl;
else if (broken > 1) // 有超过一块的硬盘坏掉了,没救了
cout << '-' << endl;
else
{
string str = "00000000";
for (int i = 0; i < n; i++)
if (working[i])
xor_string(str, get_block(i, band, pos));
cout << str << endl;
}
}
catch (exception e)
{
cout << '-' << endl;
}
}
return 0;
}
Author: ssttkkl
Link: https://ssttkkl.github.io/CSP/2019/12/%E3%80%90CSP-201903%E3%80%91%E5%A3%8A%E3%82%8C%E3%81%9FRAID-5/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.