CCF-CSP题解 201903-3 损坏的RAID5
先吐槽先吐槽!因为输入太大,需要用fgets,读n个字符或读到回车终止。
char *fgets(char *str, int n, FILE *stream)
因为scanf模拟考试T了10+次。因为IO超时的题目都是乐色!(x
用数组存磁盘信息。\(char [1000][40960*2]\)不会爆。静态数据区一般2G大小。
然后就是模拟。计算每个询问块号的条带号、单个磁盘条带号、磁盘号。分情况讨论。
%x小写16进制,%X大写。%d十,%o八,%b二。
#include <bits/stdc++.h>
const int maxn = 1000;
const int maxm = 40960;
using namespace std;
char disk[maxn+10][maxm*2+10];
int vis[maxn+10];
int len, got = 0;
int main()
{
int n, s, l;
scanf("%d%d%d", &n, &s, &l);
memset(vis, 0, sizeof(vis));
for (int i = 1, x; i <= l; i++)
{
scanf("%d ", &x);
vis[x] = 1;
fgets(disk[x], maxm*2 + 10, stdin);
if (!got)
{
len = strlen(disk[x]) / 8 / s - 1;
got = 1;
}
}
int m;
scanf("%d", &m);
while (m--)
{
int b;
scanf("%d", &b);
int stripe = b / s;
int k = stripe / (n-1);
int diskNum = (n - k%n + stripe % (n-1)) % n;
if (k > len || (n-l >= 2 && !vis[diskNum]))
{
printf("-\n");
}
else
{
int st = (k*s + b%s) * 8, en = st + 7;
if (vis[diskNum])
{
for (int i = st; i <= en; i++)
printf("%c", disk[diskNum][i]);
printf("\n");
}
else
{
for (int i = st; i <= en; i++)
{
int ans = 0;
for (int j = 0, tmp; j <= n-1; j++)
{
if (j != diskNum)
{
if (disk[j][i] >= '0' && disk[j][i] <= '9')
{
tmp = disk[j][i] - '0';
}
else
{
tmp = disk[j][i] - 'A' + 10;
}
ans ^= tmp;
}
}
printf("%X", ans);
}
printf("\n");
}
}
}
return 0;
}