介绍
磁盘是一个线性容器,其块0
通过索引size-1
。
文件是该文件使用的块索引的命名列表。
示例文件系统表示如下:
15 ALPHA=3,5 BETA=11,10,7
“磁盘有15个块,文件ALPHA的第一个块是索引3处的磁盘块。”
磁盘映射可以这样绘制:
Block Index 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
Contents | | | |A0 | |A1 | |B2 | | |B1 |B0 | | | |
当磁盘中的所有文件连续存储时,该磁盘将被视为已碎片整理。
你的目标:
发出最短的合法移动序列,以对给定的磁盘进行碎片整理。
法律行动
移动包含三部分信息:文件名,要移动的文件中的块的索引以及要移动到的磁盘块的索引。
例如
ALPHA:1>4
“将文件ALPHA的块1移动到磁盘的块4。”
此举之后,示例文件系统现在是
15 ALPHA=3,4 BETA=11,10,7
Block Index 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
Contents | | | |A0 |A1 | | |B2 | | |B1 |B0 | | | |
先前居住的磁盘块被隐式清除。同样,您可以将其视为交换磁盘上的两个块,但是交换中的一个块必须为空。
数据可能不会被破坏。文件在任何阶段都不能共享块,并且移动必须在磁盘范围内。以下举动是非法的:(ALPHA:0>10
由BETA拥有),ALPHA:3>0
(在ALPHA中没有这样的块),ALPHA:0>-1
(没有这样的磁盘索引),ALPHA:0>15
(磁盘索引太大)
例子1
完整解决以上示例。
ALPHA:0>4
BETA:0>9
BETA:2>11
文件在解决方案中不必相邻,而在它们内部是连续的。
例子2
这是一个更受约束的情况
输入:
10 A=1,2,3 B=6,7,8 C=4,5,0
输出:
B:2>9
B:1>8
B:0>7
C:2>6
该文件系统的进程为:
Block Index 00 01 02 03 04 05 06 07 08 09
Contents |C2 |A0 |A1 |A2 |C0 |C1 |BO |B1 |B2 | |
|C2 |A0 |A1 |A2 |C0 |C1 |BO |B1 | |B2 |
|C2 |A0 |A1 |A2 |C0 |C1 |BO | |B1 |B2 |
|C2 |A0 |A1 |A2 |C0 |C1 | |B0 |B1 |B2 |
| |A0 |A1 |A2 |C0 |C1 |C2 |B0 |B1 |B2 |
另一种方式来进行碎片整理这将通过向C:2>9
再带上A
下一个步骤,然后将C
下一个步骤,然后执行C:2>5
,但因为它含有比其他更多的动作,这将不是一个合法的解决方案。
表示
您可以对输入使用任何表示形式,只要它与基本字符串相当接近即可。根据您的语言,第一个示例的输入可能表示为
"15 ALPHA=3,5 BETA=11,10,7"
[15," ","ALPHA","=",3,",",5," ","BETA","=",11,",",10,",",7]
(15,(("ALPHA",(3,5)),("BETA",(11,10,7))))
etc
类似地,输出可以是您所用语言所方便的任何东西,因为它是打印出来的日志,易于阅读,并且代表合法动作的有序列表,每个动作都由1)file-name,2)file-block-index描述,3)new-disk-block-index
"ALPHA:1>6 BETA:2>9"
(0=>(0=>"ALPHA",1=>"1",2=>"6"), 1=>(0=>"BETA",1=>"2",2=>"9"))
["ALPHA",1,6,"BETA",2,9]
etc
要求
您的代码必须接受任何大小的磁盘以及任何数量和大小的文件。
没有描述合法的初始文件系统状态的输入可能导致未定义的行为。
对于任何定义明确的输入,您的代码必须产生最短的动作解决方案。
您产生的所有举动必须合法;在应用您产生的每个步骤之后,文件系统必须处于有效状态。
您的代码必须针对所有有效输入而终止,即,它绝不应陷入循环中,在应用每次移动后文件系统应处于明显新的状态。
如果存在多个最短的解决方案,则可以选择任何一个作为有效解决方案。
最短的代码胜出。请在您的代码中至少发布一个新的非平凡示例输入及其输出。