题目描述
考虑将如此安排在一个 3 x3 行列中的九个时钟:
|-------| |-------| |-------|
| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C
|-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F
|-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I
目标要找一个最小的移动顺序次将所有的指针指向12点。
下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。
选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。
移动方法 受影响的时钟
1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI
Example
9 9 12 9 12 12 9 12 12 12 12 12 12 12 12
6 6 6 5 -> 9 9 9 8-> 9 9 9 4 -> 12 9 9 9-> 12 12 12
6 3 6 6 6 6 9 9 9 12 9 9 12 12 12
[但这可能不是正确的方法,请看下面]
PROGRAM NAME: clocks
INPUT FORMAT
第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。
9 9 12
6 6 6
6 3 6
OUTPUT FORMAT
单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。
如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。
考虑将如此安排在一个 3 x3 行列中的九个时钟:
|-------| |-------| |-------|
| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C
|-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F
|-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I
目标要找一个最小的移动顺序次将所有的指针指向12点。
下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。
选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。
移动方法 受影响的时钟
1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI
Example
9 9 12 9 12 12 9 12 12 12 12 12 12 12 12
6 6 6 5 -> 9 9 9 8-> 9 9 9 4 -> 12 9 9 9-> 12 12 12
6 3 6 6 6 6 9 9 9 12 9 9 12 12 12
[但这可能不是正确的方法,请看下面]
PROGRAM NAME: clocks
INPUT FORMAT
第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。
数字的含意和上面第一个例子一样。
9 9 12
6 6 6
6 3 6
OUTPUT FORMAT
单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。
如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。
SAMPLE OUTPUT (file clocks.out)
4 5 8 9
总结:
这就是一道非常非常典型的广搜题,我们只需要用一个九维数组来模拟bz,但是不要用3..12,要压缩成1..4
代码:(pascal)
const
data:array[1..9,0..5]of longint=((4,1,2,4,5,0),
(3,1,2,3,0,0),
(4,2,3,5,6,0),
(3,1,4,7,0,0),
(5,2,4,5,6,8),
(3,3,6,9,0,0),
(4,4,5,7,8,0),
(3,7,8,9,0,0),
(4,5,6,8,9,0));
var
i,j,n,m,head,tail,k,l:longint;
a:array[0..300000,0..10]of longint;
bz:array[1..4,1..4,1..4,1..4,1..4,1..4,1..4,1..4,1..4] of boolean;
map:array[1..9]of longint;
function pd(t:longint):boolean;
var
i:longint;
begin
for i:=1 to 9 do
if a[t,i]<>4 then exit(false);
exit(true);
end;
procedure paint(t:longint);
begin
if a[t,0]>1 then
paint(a[t,0]);
write(a[t,10],' ');
end;
begin
for i:=1 to 9 do
begin
read(map[i]);
map[i]:=map[i] div 3;
end;
head:=0;
tail:=1;
for i:=1 to 9 do
a[1,i]:=map[i];
bz[map[1],map[2],map[3],map[4],map[5],map[6],map[7],map[8],map[9]]:=true;
repeat
inc(head);
for i:=1 to 9 do
begin
inc(tail);
a[tail]:=a[head];
a[tail,0]:=head;
a[tail,10]:=i;
for j:=1 to data[i,0] do
begin
inc(a[tail,data[i,j]]);
if a[tail,data[i,j]]>4 then a[tail,data[i,j]]:=1;
end;
if bz[a[tail,1],a[tail,2],a[tail,3],a[tail,4],a[tail,5],a[tail,6],a[tail,7],a[tail,8],a[tail,9]] then
dec(tail)
else
begin
bz[a[tail,1],a[tail,2],a[tail,3],a[tail,4],a[tail,5],a[tail,6],a[tail,7],a[tail,8],a[tail,9]]:=true;
if pd(tail) then
begin
paint(tail);
halt;
end;
end;
end;
until head>=tail;
end.
本文介绍了一个经典的广度优先搜索算法案例——3x3时钟谜题。通过定义九个时钟及其旋转操作,寻找最少步骤使所有时钟指针指向12点的方法。使用Pascal语言实现,详细解释了状态表示和搜索过程。
1139

被折叠的 条评论
为什么被折叠?



