KOBOSP

导航

经典问题----马踏棋盘问题(递归回溯)

问题简述:

国际象棋的棋盘为8*8的方格棋盘。现将”马”放在任意指定的方格中,按照”马”走棋的规则将”马”进行移动。要求每个方格只能进入一次,最终使得”马”走遍棋盘的64个方格。

思路简介:

我们可以根据行走规则,得出在最复杂的情况下,我们可以有8种线路,如图所示:根据输入的位置,我们对各个情况进行逐一尝试,如果当前选定的位置为合适,则递归进入下一层,再次选择合适的位置;如果有没有下一步合适的地方,则回到上一步,选择另外一种情况。此为一种低效的代码,理论上最多可以有8^64次尝试,速度炒鸡慢,还有一种贪心的优化算法。

基础代码:

#include <iostream>
#include <cmath>
#include<stdio.h>
#include <cstdio>
#include <cstring>
#include<algorithm>
#include<time.h>
using namespace std;


#define X 8 #define Y 8 int chess[X][Y]; //找到基于x,y位置的下一个可走位置 int nextxy(int *x, int *y, int count) { switch (count) { case 7://列举共8种情况 if (*x -1 >=0 && *y +2 <= Y - 1 && chess[*x -1][*y +2] == 0) { *x -=1; *y +=2; return 1; } break; case 1: if (*x + 2 <= X - 1 && *y + 1 <= Y - 1 && chess[*x + 2][*y + 1] == 0) { *x += 2; *y += 1; return 1; } break; case 3: if (*x + 1 <= X - 1 && *y + 2 <= Y - 1 && chess[*x + 1][*y + 2] == 0) { *x += 1; *y += 2; return 1; } break; case 0: if (*x + 2 <= X - 1 && *y - 1 >=0 && chess[*x + 2][*y - 1] == 0) { *x += 2; *y -= 1; return 1; } break; case 2: if (*x + 1 <= X - 1 && *y - 2 >=0 && chess[*x + 1][*y -2] == 0) { *x += 1; *y -= 2; return 1; } break; case 6: if (*x -1 >=0 && *y -2 >=0 && chess[*x-1][*y -2] == 0) { *x -=1; *y -=2; return 1; } break; case 4: if (*x - 2 >= 0 && *y - 1>=0 && chess[*x - 2][*y - 1] == 0) { *x -= 2; *y -= 1; return 1; } break; case 5: if (*x - 2 >= 0 && *y + 1 <= Y - 1 && chess[*x - 2][*y + 1] == 0) { *x -= 2; *y += 1; return 1; } break; default: break; } return 0; } int print()//迭代打印矩阵 { int i, j; for (i = 0; i < X; i++) { for (j = 0; j < Y; j++) { printf(" %2d ", chess[i][j]);//%2d为了格式好看 } printf("\n"); } printf("\n"); return 0; } int travelchessboard(int x, int y, int tag)//tag为当前所选的位置是这是在为马找第几个的落脚点,即层数 { int x1 = x, y1 = y, flag = 0, count = 0;//count为当前位置可以选择的下一步第几条路 chess[x][y] = tag;//将层数赋值给本为0的位置 if (X*Y == tag) { //如果所有位置已经安排好,则打印棋盘 print(); return 1; } //找到马的下一个可走目标(x1,y1)如果找到则flag=1,否则为0 flag = nextxy(&x1, &y1, count); while (0 == flag&&count < 7)//给第一步找路//如果当前位置下一步的路还没走完,则选择另外一条路 { count++; flag = nextxy(&x1, &y1, count);//直到路走完或者找到下一个可走的路 } while (flag)//同上,给后续几步找路,如果第一步没找打路,就直接返回0. { if (travelchessboard(x1, y1, tag + 1))//进入寻找下一层的路 { return 1; } //继续找,找到马的下一个可走目标(x1,y1)如果找到 flag=1,否则为0 x1 = x; y1 = y; count++; flag = nextxy(&x1, &y1, count); while (0 == flag&&count < 7) { count++; flag = nextxy(&x1, &y1, count); } } if (0 == flag) { chess[x][y] = 0;//找不到,就复原 } return 0; } int main() { int i, j; clock_t start, finsh;//初始化开始结束时间 start = clock();//开始时间记录 for (i = 0; i < X; i++)//矩阵赋值 { for (j = 0; j < Y;j++) { chess[i][j] = 0; } } if (!travelchessboard(0, 0, 1))//进入函数 { printf("\nfail");//如果遍历完还没有搜索到合适的路径,打印fail } finsh = clock();//结束时间记录 printf("\nthe total time is:%fs\n", (double)(finsh - start) / CLOCKS_PER_SEC);//显示总时间 return 0; }

  

建议:千万不要去尝试这个方法,电脑会炸的。

posted on 2018-02-03 14:14  KOBOSP  阅读(1621)  评论(0)    收藏  举报