分析:
本题的难点在于读懂题目>_<。
定义哈希表disks,用于存储输入的磁盘信息。disks以磁盘的顺序号为键,以该磁盘上存储的数据为值。
阵列中的条带大小为s(单位:块),现存的硬盘数目为l。
1.块、条带、磁盘均从0开始连续编号。
2.块的大小是4个字节,而输入的是16进制数字。1个字节需要用2个16进制数字表示,因此,1个块中的数据需要用8个16进制数字表示。
3.编号为b的块,在阵列中的条带编号band为
$$
band = \left \lfloor \frac {b}{s} \right \rfloor
$$
4.编号为band的条带,所在的磁盘编号diskId为
$$
diskId = band \ \% \ 磁盘数量
$$
5.“对于有(n+1)块硬盘的RAID5存储,我们利用每块硬盘上编号为k的条带,存储编号为[kn, (k+1)n)的条带(共n个)。”编号为band的条带,在磁盘diskId上的条带编号k为
$$
k = \frac{band}{n} = \frac{条带编号}{磁盘数量-1}
$$
6.阵列中编号为b的块,在磁盘diskId上的块号block为
$$
block = k \times s + b \ \% \ s
$$
7.如果读操作由于下列情形之一无法进行,则输出一个减号(-):
(1)阵列不完整,且被读取的块所在的硬盘缺失,且该数据无法由现存的硬盘数据推算出来,即 disks不包含diskId && n - l > 1
;
(2)指定的块超出阵列总长度,即(block + 1) * 8 > diskId上存储的数据的长度
8.如果disks包含块b所在的磁盘编号diskId,则直接输出块block中存储的数据;否则,需要对其他磁盘上第block块中存储的数据进行异或运算。
9.由于磁盘数量n的最大值为$10^3$,而每块硬盘上的数据长度小于40KB($40 \times 1024 \times 2 \approx 8 \times 10^4$个字符)。因此,输入的磁盘数据将多达$8 \times 10^4 \times 10^3 = 8 \times 10^7$个字符。因此,在C++中使用scanf或者cin(Java中使用Scanner)读取数据,都将会出现运行超时。
实践发现:在C++中,使用fgets读入磁盘存储的数据;在Java中,使用BufferedReader,能够正确通过所有的测试用例。
- C++版
1 |
|
- Java版
1 | import java.io.BufferedReader; |