骑士巡游问题
Posted JackGo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了骑士巡游问题相关的知识,希望对你有一定的参考价值。
问题:
在 n × n 方格的国际象棋棋盘上,马(也称为骑士Knight)从任意指定的方格出发,以跳马规则(横一步竖两步或横两步竖一步),周游棋盘的每一个格子,要求每个格子只能跳过一次。
代码:
思路什么的都在代码里,但是我写的代码太肤浅了, 5*5 的规模都要跑半天。
所以真切的希望大家能够提出对我算法的批评与指教。
#include<iostream> #include<fstream> using namespace std; //定义了8个方向,N表示右上的那个位置 #define N 0 #define NE 1 #define E 2 #define SE 3 #define S 4 #define SW 5 #define W 6 #define NW 7 struct step {//骑士巡游过的地方 int x; int y; }; void display(step steps[], int n) {//展示骑士巡游的过程 ofstream output("output.txt"); int patch[10][10]={0}; for (int i = 1; i <= n*n; i++) { patch[steps[i].x][steps[i].y]=i; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cout<<patch[i][j]<<" "; output<<patch[i][j]<<" "; } cout<<endl; output<<endl; } cout<<endl; output<<endl; } bool isInside(int n, step place) {//判断是否走出了地图 if (place.x<1 || place.x>n || place.y<1 || place.y>n) return false; return true; } bool isOverlap(int map[][8], step place) {//判断是否走重了 if (map[place.x][place.y] == 1) return true; return false; } step overlook(step now, int dir) {//往dir方向向前看一步,返回这样走之后的位置 step then; switch (dir) { case N:then.x = now.x + 1, then.y = now.y - 2; break; case NE:then.x = now.x + 2, then.y = now.y - 1; break; case E:then.x = now.x + 2, then.y = now.y + 1; break; case SE:then.x = now.x + 1, then.y = now.y + 2; break; case S:then.x = now.x - 1, then.y = now.y + 2; break; case SW:then.x = now.x - 2, then.y = now.y + 1; break; case W:then.x = now.x - 2, then.y = now.y - 1; break; case NW:then.x = now.x - 1, then.y = now.y - 2; break; } return then; } void patrol(step steps[], int now, step then, int map[][8]) {//从now的位置向dir方向巡游下一步 steps[now + 1] = then; //在map上标记已经走过 map[steps[now + 1].x][steps[now + 1].y] = 1; } void KnightPatrol(int n, int count, step steps[], int map[][8]) {//n表示棋盘规模,count表示骑士已经走过的步数,steps记录骑士巡游过的点,map用来标记地图上每个点有没被走过 if (count > n*n) {//如果骑士巡游过了所有的点 display(steps, n); } for (int i = N; i <= NW; i++) {//对每个方向遍历 step then = overlook(steps[count], i);//向i方向眺望一下 if (isInside(n, then) && !isOverlap(map, then)) {//如果骑士下一步没有跑到地图外面,且没有走到刚才走过的地方 patrol(steps, count, then, map); for(int k=1;k<=count+1;k++) { cout<<steps[k].x<<","<<steps[k].y<<" "; } cout<<endl; KnightPatrol(n, count + 1, steps, map); map[steps[count+1].x][steps[count+1].y]=0; } } } int main() { int n; cin >> n; step *steps = new step[n*n + 1]; steps[1].x = 3; steps[1].y = 1; int map[8][8] = { 0 }; map[3][1] = 1; KnightPatrol(n, 1, steps, map); system("pause"); }
以上是关于骑士巡游问题的主要内容,如果未能解决你的问题,请参考以下文章
骑士巡游的问题简述如下:在国际象棋盘上某一位置放置一个马的棋子,然后采用象棋中“马走日字”规则