骑士走棋盘

问题陈述:

  骑士游历(Knight tour)在十八世纪初备受数学家与拼图迷的注意,究竟它是什么时候被提出已不可考。骑士的走法为国际象棋的走法,类似中国象棋的马,骑士可以由任意一个位置出发,他如何走完所有的位置?

问题解法:

  骑士的走法,基本上可以用递归的方法来解决,但是纯粹的递归在维度大时相当没有效率。一个聪明的解法由J.C.Warnsdorff在1823年提出,简单的说,先将最难的位置走完,接下来的路就是宽广,骑士所要走的下一步:为下一步再做选择时,所能走的步数最少的一步。使用这个方法,在不使用递归的情况下,可以有较高的几率找出走法(有时可能也找不到走法)。

代码详解:

  1 #include <iostream>
  2 #include <cstdio>
  3
  4 using namespace std;
  5
  6 int pos[8][8] = {0};
  7
  8 int travel(int, int);
  9
 10 int main()
 11 {
 12     int i, j, startX, startY;
 13     printf("Please input a starting point: ");
 14     scanf("%d%d", &startX, &startY);
 15     if(travel(startX, startY)) {
 16         printf("Travel finished\n");
 17     }else {
 18         printf("Travel failed\n");
 19     }
 20     for(i=0; i<8; i++) {
 21         for(j=0; j<8; j++) {
 22             printf("%2d ", pos[i][j]);
 23         }
 24         printf("\n");
 25     }
 26     return 0;
 27 }
 28
 29 int travel(int x, int y) {
 30     int i, j, k, l, m;
 31     int tmpX, tmpY;
 32     int count, min, tmp;
 33
 34     //骑士可走的八个方向(顺时针)
 35     int ktmoveX[8] = {1, 2, 2, 1, -1, -2, -2, -1};
 36     int ktmoveY[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
 37
 38     //下一步坐标
 39     int nextX[8] = {0};
 40     int nextY[8] = {0};
 41
 42     //记录每个方向的出路的个数
 43     int exists[8] = {0};
 44
 45     //起始用1标记位置
 46     i = x;
 47     j = y;
 48     pos[i][j] = 1;
 49
 50     //遍历棋盘
 51     for(m=2; m<=64; m++) {
 52         //初始化八个方向出口个数
 53         for(l=0; l<8; l++) {
 54             exists[l] = 0;
 55         }
 56         l = 0; //计算可走方向
 57
 58         //试探八个方向
 59         for(k=0; k<8; k++) {
 60             tmpX = i + ktmoveX[k];
 61             tmpY = j + ktmoveY[k];
 62             //边界 跳过
 63             if(tmpX<0 || tmpY<0 || tmpX>7 || tmpY>7) {
 64                 continue;
 65             }
 66             //可走 记录
 67             if(pos[tmpX][tmpY] == 0) {
 68                 nextX[l] = tmpX;
 69                 nextY[l] = tmpY;
 70                 l++;    //可走方向加1
 71             }
 72         }
 73         count = l;
 74         //无路可走 返回
 75         if(count == 0) {
 76             return 0;
 77         //一个方向可走 标记
 78         }else if(count == 1) {
 79             min = 0;
 80         //找出下个位置出路个数
 81         }else {
 82             for(l=0; l<count; l++) {
 83                 for(k=0; k<8; k++) {
 84                     tmpX = nextX[l] + ktmoveX[k];
 85                     tmpY = nextY[l] + ktmoveY[k];
 86                     if(tmpX<0 || tmpY<0 || tmpX>7 || tmpY>7) {
 87                         continue;
 88                     }
 89                     if(pos[tmpX][tmpY] == 0) {
 90                         exists[l]++;
 91                     }
 92                 }
 93             }
 94             //找出下个位置出路最少的方向
 95             min = 0;
 96             tmp = exists[0];
 97             for(l=0; l<count; l++) {
 98                 if(exists[l] < tmp) {
 99                     tmp = exists[l];
100                     min = l;
101                 }
102             }
103         }
104         //用序号标记走过的位置
105         i = nextX[min];
106         j = nextY[min];
107         pos[i][j] = m;
108     }
109     return 1;
110 }

测试效果图:

测试数据:startX = 2, startY = 2

转载请注明出处:http://www.cnblogs.com/michaelwong/p/4287075.html

时间: 2024-08-27 14:30:39

骑士走棋盘的相关文章

【骑士走棋盘】

/* 骑士走棋盘 说明: 骑士旅游Knight tour在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋 棋的走法,骑士可以由任一个位置出发,它要如何走完所有的位置. 解法: 骑士的走法,基本上可以用递回来解决,但是纯粹的递回在维度大时相当没有效率,一个聪明的解法由J.CWarnsdorff 在1823年提出, 简单地说,先将最难的位置走完,接下来的路就宽广了,骑士所想要的下一步,为下一不再 选 择时,所能走的步数最少的一步.使用这个方法,在不使用递回的情况下,可

骑士走棋盘问题

1.输出棋牌 #include <stdio.h> #include <stdlib.h> #include <math.h> void main() { int i,j; system("cmd /c chcp 437"); for(i=0;i<8;i++) { for(j=0;j<8;j++) if((i+j)%2==0) printf("%c",219); else printf(" ");

F: Horse Pro 马走棋盘 BFS

F: Horse Pro 豆豆也已经开始学着玩象棋了,现在豆豆已经搞清楚马的走法了,但是豆豆不能确定能否在 100 步以内从一个点到达另一个点(假设棋盘无限大). Input 第一行输入两个整数 x1,y1 表示当前马所在的位置. 第二行输入两个整数 x2,y2 表示豆豆想把马走在的位置. −10000≤x1,x2,y1,y2≤10000 Output 如果能够在100步以内(包括100步)从(x1,y1) 到达 (x2,y2) 则输出到达所需要的最小步数,否则输出 −1 Sample Inpu

java 经典算法(转)

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

【经典算法大全】收集51种经典算法 初学者必备

<经典算法大全>是一款IOS平台的应用.里面收录了51种常用算法,都是一些基础问题.博主觊觎了好久,可悲哀的是博主没有苹果,所以从网上下了老奔的整理版并且每个都手敲了一遍. 虽然网上也有博客贴了出来,但是自己写写感觉总是好的.现在分享个大家. 代码和运行结果难免有出错的地方,请大家多多包涵. 1.河内之塔(汉诺塔) 2.费式数列 3.巴斯卡三角形 4.三色棋 5.老鼠走迷宫(1) 6.老鼠走迷宫(2) 7.骑士走棋盘 8.八皇后 9.八枚银币 10.生命游戏 11.字串核对 12.双色河内塔,

经典算法大全

原文地址:经典算法大全 作者:liurhyme 经                                                                    典                                                                    算                                                                    法                  

searchhd1010

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on ex

经典算法-回顾(前十)

关于 曾经的48种经典算法与23种常用设计模式相信都不陌生了,不过好久没看了而且当时看的时候也没有整理出来,现在就慢慢整理出来(后续会慢慢更新,这里只是对经典算法进行整理): 目录: 1.河内之塔_TowersOfHanoi2.费氏数列_Fibonacci3.巴斯卡三角形4.三色棋5.老鼠走迷官16.老鼠走迷官27.骑士走棋盘_KnightTour8.八皇后9.八枚银币10.生命游戏 先来看看基本说明和解法: 1.河内之塔_TowersOfHanoi 说明 河内之塔(Towers of Hano

java学习-4 经典算法

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip: