算法思考--------骑士走棋盘(c语言)
2014-03-25 23:10
162 查看
一、规则说明
骑士可以从任意一个位置出发,走法和中国象棋的"马"走法类似,"走日"。问:如何走完所有的位置
二、解法
可以用递归的方法解决,但是纯粹的递归在维度大时没有效率。一个聪明的解法由J.C.Warnsdorft提出:先将最难的位置走完,接下来的路就宽广了
三、代码实现
#include <stdio.h> int travel(int x, int y); int board[8][8] = {0}; //代表整个棋盘 int main(void) { int startx, starty; //记录起点 int i, j; printf("输入起始点:"); scanf("%d %d", &startx, &starty); if(travel(startx, starty)) { printf("游历完成\n"); } else { printf("游历失败\n"); } for(i = 0; i < 8; i++) //打印 { for(j = 0; j < 8; j++) { printf("%2d ", board[i][j]); } putchar('\n'); } return 0; } int travel(int x, int y) { int ktmove1[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; //这两行对应一个点可以走的八个方向的坐标 int ktmove2[8] = {1, 2, 2, 1, -1, -2, -2, -1}; // int nexti[8] = {0}; //这两行存储的是可走的下一步的坐标 int nextj[8] = {0}; // int exists[8] = {0}; //记录每个可走下一步的可走下一步个数 int i, j, k, m, l; int tmpi, tmpj; int count, min, tmp; i = x; j = y; board[i][j] = 1; //将起点坐标置为1 for(m = 2; m <= 64; m++)//通过循环来标记2-64 { for(l = 0; l < 8; l++) exists[l] = 0; //这个数组是每次循环都要重复利用的,所以重置0 l = 0; //这个l也是重复利用的 for(k = 0; k < 8; k++) //通过循环判断一个坐标的八个方向是否可走 { tmpi = i + ktmove1[k]; tmpj = j + ktmove2[k]; if(tmpi < 0 || tmpj < 0 || tmpi > 7 || tmpj > 7) //通过此来筛选是否可走 continue; if(board[tmpi][tmpj] == 0)//如果可走,就将可走的坐标存储在nexti,nextj中 { nexti[l] = tmpi; nextj[l] = tmpj; l++; //把下一步可走位置加一 } } count = l; //将可走位置的数目赋值给count来进行一下判断 if(count == 0)//没有下一步可走,就返回 { return 0; } else if(count == 1)//只有一个位置可走,就选择这一步,然后继续循环 { min = 0; } else //有多个位置可走时,判断哪一个可走位置的下一步的可走位置最少,就走这一步,意思是把 { //把最困难的走了,这样接下来的空间就大了,可以走完所有位置的可能性就变大了 for(l = 0; l < count; l++) //同时也说明这种非递归的方法不一定对于所有初始位置都能 { //走遍全图,因为毕竟这种算法使用概率的原理 for(k = 0; k < 8; k++) { tmpi = nexti[l] + ktmove1[k]; tmpj = nextj[l] + ktmove2[k]; if(tmpi < 0 || tmpj < 0 || tmpi > 7 || tmpj > 7) { continue; } if(board[tmpi][tmpj] == 0) exists[l]++; //记录可走位置下一步可走位置的个数 } } tmp = exists[0]; min = 0; for(l = 1; l < count; l++) { if(exists[l] < tmp) //取得可走位置下一步可走位置最少的那个坐标 { tmp = exists[l]; min = l; } } } i = nexti[min]; j = nextj[min]; board[i][j] = m; //将当前步数赋值给那个可走位置下一步可走位置最少的那个坐标 } return 1; }四、效果展示
相关文章推荐
- 马踏棋盘问题(骑士周游问题)及其优化算法java实现
- 马踏棋盘算法(骑士周游问题)
- 马踏棋盘算法(骑士周游问题)- 数据结构和算法60
- 数据结构与算法10:马踏棋盘问题(骑士周游问题)
- 马踏棋盘算法(骑士周游问题)- 数据结构和算法60
- 数据结构经典算法(7)骑士走棋盘
- 算法思考-------杨辉三角(c语言)
- Knight Tour 骑士走棋盘算法(附代码)
- 棋盘覆盖问题、半数集问题算法解析-C语言
- 算法思考--------汉诺塔c语言实现-------递归
- 算法训练-骑士走棋盘
- 骑士走棋盘——C语言经典算法
- 每天一算法(骑士走棋盘)
- 马踏棋盘算法 [骑士周游问题] --->图
- C语言-数据结构-骑士周游-马踏棋盘问题-源代码
- 经典游戏算法之骑士走棋盘
- [算法]图算法之骑士遍历问题(象棋中马的遍历问题)分析,C语言实现
- [算法]C语言实现 骑士旅游(递归)
- 小甲鱼数据结构和算法--马踏棋盘(骑士周游问题)
- 经典游戏算法之骑士走棋盘