问题描述:
在 8×8 的国际象棋棋盘上,用一个马按照马步跳遍整个棋盘,要求每个格子都只跳到一次,并且全部跳完。
解法思路:
在8x8的棋盘上,左上角的马能走的位置肯定比中间或其他地方要少的,所以为了简化问题与减少算法所需时间,我们把棋盘扩充为12x12的,那么在正中间的8x8棋盘中,我们能够让每一匹马都有八个方位能走。再把这八个位置的偏量放置一个数组里面方便计算。递归与非递归的思路是相似的,只是非递归需要借助栈来记录上一步的位置,以及上一步到当前步的循环变量 i 的值。
int move[ 8 ] [ 2 ] = { { 1 , - 2 } , { 2 , - 1 } , { 2 , 1 } , { 1 , 2 } , { - 1 , 2 } , { - 2 , 1 } , { - 2 , - 1 } , { - 1 , - 2 } } ;
递归代码:
#include <stdio.h>
int chess[ 12 ] [ 12 ] = { 0 } ;
int cnt = 0 ;
int countChess = 0 ;
int move[ 8 ] [ 2 ] = { { 1 , - 2 } , { 2 , - 1 } , { 2 , 1 } , { 1 , 2 } , { - 1 , 2 } , { - 2 , 1 } , { - 2 , - 1 } , { - 1 , - 2 } } ;
int initChess ( ) ;
void printChess ( ) ;
void horse ( int x, int y) ;
int main ( void ) {
initChess ( ) ;
int i, j;
for ( i- 2 ; i< 10 ; i++ ) {
for ( j= 2 ; j< 10 ; j++ ) {
cnt = 1 ;
chess[ i] [ j] = cnt;
horse ( i, j) ;
}
}
}
void horse ( int x, int y) {
int i, j;
for ( i= 0 ; i< 8 ; i++ ) {
int row = x + move[ i] [ 0 ] ;
int col = y + move[ i] [ 1 ] ;
if ( chess[ row] [ col] == 0 ) {
chess[ row] [ col] = ++ cnt;
if ( cnt == 64 ) {
++ countChess;
printChess ( ) ;
cnt-- ;
chess[ row] [ col] = 0 ;
break ;
} else {
horse ( row, col) ;
cnt-- ;
chess[ row] [ col] = 0 ;
}
}
}
}
int initChess ( ) {
int i, j;
for ( i= 0 ; i< 12 ; ++ i) {
for ( j= 0 ; j< 12 ; ++ j) {
if ( i< 2 || i> 9 || j< 2 || j> 9 ) {
chess[ i] [ j] = - 1 ;
}
}
}
}
void printChess ( ) {
printf ( "第%d个解是:\n" , countChess) ;
int i, j;
for ( i= 2 ; i< 10 ; ++ i) {
for ( j= 2 ; j< 10 ; ++ j) {
printf ( "%2d " , chess[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
printf ( "***********************\n" ) ;
}
非递归代码:
#include <stdio.h>
int chess[ 12 ] [ 12 ] = { 0 } ;
int cnt = 0 ;
int countChess = 0 ;
int move[ 8 ] [ 2 ] = { { 1 , - 2 } , { 2 , - 1 } , { 2 , 1 } , { 1 , 2 } , { - 1 , 2 } , { - 2 , 1 } , { - 2 , - 1 } , { - 1 , - 2 } } ;
int initChess ( ) ;
void printChess ( ) ;
void horse ( int x, int y) ;
struct Node{
int x;
int y;
int i;
} chessStep[ 64 ] ;
int top = - 1 ;
int main ( void ) {
initChess ( ) ;
int i, j;
for ( i= 2 ; i< 10 ; i++ ) {
for ( j= 2 ; j< 10 ; j++ ) {
cnt = 1 ;
chess[ i] [ j] = cnt;
horse ( i, j) ;
}
}
}
void horse ( int x, int y) {
int i = 0 ;
while ( cnt < 64 ) {
int row;
int col;
for ( i; i< 8 ; i++ ) {
row = x + move[ i] [ 0 ] ;
col = y + move[ i] [ 1 ] ;
if ( chess[ row] [ col] == 0 ) {
break ;
}
}
if ( i != 8 ) {
chess[ row] [ col] = ++ cnt;
chessStep[ ++ top] . x = x;
chessStep[ top] . y = y;
chessStep[ top] . i = i;
if ( cnt == 64 ) {
printChess ( ) ;
chess[ row] [ col] = 0 ;
i = chessStep[ top] . i + 1 ;
x = chessStep[ top] . x;
y = chessStep[ top] . y;
top-- ;
cnt-- ;
} else {
x = row;
y = col;
i = 0 ;
}
} else {
chess[ x] [ y] = 0 ;
i = chessStep[ top] . i + 1 ;
x = chessStep[ top] . x;
y = chessStep[ top] . y;
top-- ;
cnt-- ;
}
if ( top == - 1 ) {
break ;
}
}
}
int initChess ( ) {
int i, j;
for ( i= 0 ; i< 12 ; ++ i) {
for ( j= 0 ; j< 12 ; ++ j) {
if ( i< 2 || i> 9 || j< 2 || j> 9 ) {
chess[ i] [ j] = - 1 ;
}
}
}
}
void printChess ( ) {
++ countChess;
printf ( "第%d个解是:\n" , countChess) ;
int i, j;
for ( i= 2 ; i< 10 ; ++ i) {
for ( j= 2 ; j< 10 ; ++ j) {
printf ( "%2d " , chess[ i] [ j] ) ;
}
printf ( "\n" ) ;
}
printf ( "***********************\n" ) ;
}
输出结果:
注:程序得很久很久才能跑完所有解,这只几分钟的结果图。