这道题的难点应该是如何求出来盘数和行数吧
行数计算:
设需要求的块编号为b,行数其实比较好看出来:因为存放的时候是先分成条带,再在条带里的对应块放,所以要先计算出来条带行数
条带行数:在上图中,b=6时,该块所在条带行数为1(从0开始)
块行数:b=6时,该块在其所在条带内行数为0(从0开始),在整个中块行数为2(从0开始)
我们最后要求的是该块在整体中的块行数。
思考过程如下:
每个条带行内的块数为(n-1)*s,条带行数=b/((n-1)*s),算出来的是当前块所在条带以上所有的条带行数,再*s,得到当前块所在条带以上的所有块行数。再加上该块在该条带中的行数,即为所求
b/((n-1)*s)*s+b%s
盘数计算:
我个人感觉盘数挺难想的,要不是看了别的朋友的代码,我压根不知道他有规律,下边都是自己的理解,每个人的理解应该也有差别的
因为在计算盘数的时候就只关注盘数就行,行数也可以给他改变,然后我把样例中Dsk0、Dsk1、Dsk2的块数编号分别写出来,发现其实是按顺序的
Dsk0:(0,1) (6,7).....
Dsk1:(2,3) (8,9)......
Dsk2:(4,5) (10,11).....‘
由此得出规律
盘数=b%(n*s)/s
输出为减号(-):
- 阵列不完整,且被读取的块所在的硬盘缺失,且该数据无法由现存的硬盘数据推算出来;
根据输入块数求出来的盘数不在l个盘中,且n>l+1,无法根据异或运算得出
- 指定的块超出阵列总长度。
行数+1(标号从0开始)*8>输入的字符串长度
样例1:
2 1 2
0 000102030405060710111213141516172021222324252627
1 000102030405060710111213141516172021222324252627
2
0
1
样例2:
3 2 2
0 000102030405060710111213141516172021222324252627
1 A0A1A2A3A4A5A6A7B0B1B2B3B4B5B6B7C0C1C2C3C4C5C6C7
2
2
5
自己的基础太差了,char *和char a[]根本就分不清楚
100分代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
using namespace std;
const int MAXN=1001;
const int MAXL=1024*80+5;
char disk[MAXN][MAXL];
int char2num(char c) {
if(isdigit(c)) {
return c-'0';
} else {
return c-'A'+10;
}
}
char num2char(int x) {
// return '0';
if(x>=10) {
return 'A'+x-10;
} else {
return '0'+x;
}
}
//取出盘diskid的lineid*8到(lineid+1)*8的字符串
char* substr(char* s,int lineid) {
char *res=(char *)malloc(sizeof(char)*(8));
for(int i=0; i<8; i++) {
res[i]=s[lineid*8+i];
}
return res;
}
void XOR(char* a,char*b) {
for(int i=0; i<8; i++) {
int temp=char2num(a[i])^char2num(b[i]);
a[i]=num2char(temp);
}
}
//每个块大小为4个字节
int main() {
int n,s,l; //阵列中硬盘数目为n,阵列的条带大小为s块,现存硬盘数目为l
scanf("%d%d%d",&n,&s,&l);
int index;
for(int i=0; i<l; i++) {
scanf("%d ",&index); //硬盘的顺序号
fgets(disk[index],MAXL,stdin); // //对于长字符串,请勿直接使用scanf或cin,否则超时
}
int len=strlen(disk[index]);
int m;
scanf("%d",&m); //m个请求
for(int i=0; i<m; i++) {
int b;
scanf("%d",&b);
int diskid=b%(n*s)/s;
int lineid=b/((n-1)*s)*s+b%s;
if(disk[diskid][0]=='\0' && n>l+1 || (lineid+1)*8>len) { //无法进行读取操作
printf("-\n");
continue;
}
char* res;
if(disk[diskid][0]!='\0') { //该盘直接在输入中存在
//取出盘diskid的lineid*8到(lineid+1)*8的字符串
res=substr(disk[diskid],lineid);
for(int i=0;i<8;i++){
printf("%c",res[i]);
}
printf("\n");
} else { //该盘不在输入中,但是可以通过异或运算求出来
char ans[10]="00000000";
for(int j=0; j<n; j++) {
if(j==diskid) continue;
else {
XOR(ans,substr(disk[j],lineid));
}
}
printf("%s",ans);
}
}
return 0;
}