跳马问题(骑士周游问题)初探

跳马问题也称为骑士周游问题,是算法设计中的经典问题。其一般的问题描述是:

考虑国际象棋棋盘上某个位置的一只马,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条马的周游路线。试设计一个算法找出这样一条马的周游路线。 

此题实际上是一个汉密尔顿通路问题,可以描述为:

在一个8×8的方格棋盘中,按照国际象棋中马的行走规则从棋盘上的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格,
这样的一条周游路线在数学上被称为国际象棋盘上马的哈密尔顿链。请你设计一个程序,从键盘输入一个起始方格的坐标,由计算机自动寻找并打印
出国际象棋盘上马的哈密尔顿链。

能够想到的思路是用回溯,马在每一个点最多有8种跳法,遍历所有这8种可能的跳法即可得到结果。这是回溯算法中的子集树的类型,与典型的子集树问题类型不同的是,这里每一枝有8种可能的选择,而典型的子集树问题只有0,1两种选择。

下面是该算法的实现:

/*
 * File: KnightTravel1.cpp
 * Author: eshow
 * Date: 2007-09-10
 * Question:
    考虑国际象棋棋盘上某个位置的一只马,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条马的周游路线。试设计一个算法找出这样一条马的周游路线。
 * Solution:
    使用回溯法,马每一步至多有8种跳法,遍历这8种跳法,得到结果。这是一个子集树的回溯问题,每一个step[i]都在[0, 7]之间。设棋盘大小为N * N,则时间复杂度为O(8^(N * N)),当N = 8时,算法很慢。
*/


#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< memory.h >

const   int  N  =   8 ;

int  step[N  *  N]  =   { -1} ;
int  chess[N][N]  =   { 0} ;

int  Jump[ 8 ][ 2 =   { { -2-1}{ -1-2}{ 1-2}{ 2-1}{ 21}{ 12}{ -12}{ -21}} ;

int  p  =   0 ;

int  canJump( int  x,  int  y)
{
    
if (x >= 0 && x < N && y >= 0 && y < N && chess[x][y] == 0)
        
return 1;
    
return 0;
}


void  BackTrace( int  t,  int  x,  int  y)
{
    
if (t >= N * N)
    
{
        p
++;
        
        
for (int i = 1; i <= N * N - 1++i)
        
{
            printf(
"%d ", step[i]);
        }

        printf(
" ");
        
for (int i = 0; i < N; ++i)
        
{
            
for (int j = 0; j < N; ++j)
                printf(
"%2d ", chess[i][j]);
            printf(
" ");
        }

        printf(
" ");
        exit(
1);
        
//return;
    }

    
else
    
{
        
for (int i = 0; i < 8++i)
        
  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值