骑士巡游或叫马步遍历
问题描述:
在n*n的棋盘上,假设一个骑士按象棋中“马”的走法,从初始坐标(x1,y1)出发,要求无重复地走遍棋盘
中的每一个位置(每个点必须经过一次且只能是一次 )。请编写程序,为骑士求解巡游“路线”(或无解)。
代码:
#include <iostream> #include <iomanip> using namespace std; const int n = 5; //n*n的棋盘 int a[n+1][n+1]; //二维数组表示棋盘,不使用0行0列 int move[9][3]; //移动偏移量(增量)。为方便起见,只使用其中1-8行、1-2列(不用0行0列) bool possible; //是否摆放成功 void go(int i, int j, int k, bool &possible) { /*从(i,j)点出发,做第k至第n*n次的移动 若成功则通过引用参数q返回true*/ int v = 0,g,h; //v(取值1-8)表示方向,(g,h)表示从当前点(i,j)沿v方向移动后到达点的坐标 do { v++; possible = false; g = i + move[v][1]; h = j + move[v][2]; if (g >= 1 && g <= n && h >= 1 && h <= n && a[g][h] == 0) //(g,h)处于棋盘内,且尚未放过棋子 { a[g][h] = k; //将第k步棋子放在(g,h)点 if (k < n * n) //尚未放满整个棋盘 { go(g,h,k+1,possible); //递归调用 if(!possible) a[g][h] = 0; } else //放满整个棋盘,possible返回true possible = true; } } while(!possible && (v != 8)); } int main() { //初始化move数组 move[1][1] = 2; move[1][2] = 1; move[2][1] = 1; move[2][2] = 2; move[3][1] = -1; move[3][2] = 2; move[4][1] = -2; move[4][2] = 1; move[5][1] = -2; move[5][2] = -1; move[6][1] = -1; move[6][2] = -2; move[7][1] = 1; move[7][2] = -2; move[8][1] = 2; move[8][2] = -1; cout << “Please input the first position:” << endl; int x1,y1; cin >> x1 >> y1; //输入初始坐标 a[x1][y1] = 1; //在棋盘(x1,y1)处放下棋子(第1步棋) go(x1, y1, 2, possible); //从(x1,y1)出发,做第2至第25次的移动,若成功possible返回true //若摆放成功,输出棋盘(移动过程) if (possible) for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << setw(4) << a[i][j]; cout << endl; } else //摆放不成功 cout << “Impossible!” << endl; return 0; }