|
发表于 2004-5-21 11:09:07
|
显示全部楼层
这问题用递归比较方便。
程序我已经编出来了,只不过用perl比较慢。算5X5的棋盘还行:
[php]
#!/usr/bin/perl -w
use strict;
#初始化棋盘,未走过的位置为0,走过的为1。
my $size = 5; #设置棋盘大小
my ($row, $col) = ($size - 1, $size - 1);
my @chess_table;
for my $i (0..$row) {
for my $j (0..$col) {
$chess_table[$i][$j] = 0;
}
}
#起始位置
my ($startx, $starty) = (0, 0);
my $result;
if ( $result = horse_move( $startx, $starty, @chess_table ) ) {
print "The Path is:\n$result\n";
} else {
print "No Result!\n";
}
print "\n\nAll done!\n";
###############################
sub horse_move {
my ($x, $y, @table) = @_;
my @new_table = map { [ @$_ ] } @table; #复制棋盘
$new_table[$x][$y] = 1; #设置走过的点为1
return "($x, $y)" if ( all_done( @new_table ) ); #如果棋盘上的所有点都已走过则结束递归
# 马可以走的八个位置
my @choices = ( [$x - 2, $y - 1],
[$x - 2, $y + 1],
[$x + 2, $y - 1],
[$x + 2, $y + 1],
[$x + 1, $y - 2],
[$x - 1, $y - 2],
[$x + 1, $y + 2],
[$x - 1, $y + 2] );
for my $i (0..$#choices) {
my ($nx, $ny) = @{$choices[$i]};
next if ( $nx < 0 or $nx > $row or $ny < 0 or $ny > $col ); #判断($nx, $ny)是否在棋盘之内
next if ( $new_table[$nx][$ny] ); #判断($nx, $ny)是否已走
my $result = horse_move( $nx, $ny, @new_table );
return "($x, $y) -> $result" if ( $result );
}
return 0; #如果八个位置都没有结果则返回0
}
sub all_done {
my (@tab) = @_;
for my $i ( 0..$row ) {
for my $j ( 0..$col ) {
return 0 unless ( $tab[$i][$j] ); #若存在未访问过的点,则返回0
}
}
return 1;
}
[/php]
结果:
- The Path is:
- (0, 0) -> (2, 1) -> (0, 2) -> (1, 0) -> (3, 1) ->
- (4, 3) -> (2, 2) -> (1, 4) -> (3, 3) -> (4, 1) ->
- (2, 0) -> (0, 1) -> (1, 3) -> (3, 4) -> (4, 2) ->
- (3, 0) -> (1, 1) -> (0, 3) -> (2, 4) -> (1, 2) ->
- (0, 4) -> (2, 3) -> (4, 4) -> (3, 2) -> (4, 0)
复制代码 |
|