马踏棋盘算法(骑士周游问题)——回溯法
【问题描述】
关于马踏棋盘的基本过程:国际象棋的棋盘为 8*8 的方格棋盘。现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动。要求每个方格只能进入一次,最终使得"马"走遍棋盘的64个方格。
【代码】
#include <stdio.h>
#define X 8
#define Y 8
int chess[X][Y];
//找下一个位置
bool isNextPos(int& x, int& y, int count)
{
switch (count)
{
case 0:
if (x + 1 < X && y - 2 >= 0 && chess[x + 1][y - 2] == 0) {
x = x + 1;
y = y - 2;
return true;
}
break;
case 1:
if (x + 2 < X && y - 1 >= 0 && chess[x + 2][y - 1] == 0) {
x = x + 2;
y = y - 1;
return true;
}
break;
case 2:
if (x + 2 < X && y + 1 < Y && chess[x + 2][y + 1] == 0) {
x = x + 2;
y = y + 1;
return true;
}
break;
case 3:
if (x + 1 < X && y + 2 < Y && chess[x + 1][y + 2] == 0) {
x = x + 1;
y = y + 2;
return true;
}
break;
case 4:
if (x - 1 >= 0 && y + 2 < Y && chess[x - 1][y + 2] == 0) {
x = x - 1;
y = y + 2;
return true;
}
break;
case 5:
if (x - 2 >= 0 && y + 1 < Y && chess[x - 2][y + 1] == 0) {
x = x - 2;
y = y + 1;
return true;
}
break;
case 6:
if (x - 2 >= 0 && y - 1 >= 0 && chess[x - 2][y - 1] == 0) {
x = x - 2;
y = y - 1;
return true;
}
break;
case 7:
if (x - 1 >= 0 && y - 2 >= 0 && chess[x - 1][y - 2] == 0) {
x = x - 1;
y = y - 2;
return true;
}
break;
default:
break;
}
return false;
}
//打印棋盘
void print()
{
for (int i = 0; i < X; ++i) {
for (int j = 0; j < Y; ++j) {
printf("%2d\t", chess[i][j]);
}
printf("\n");
}
printf("\n\n");
}
// 深度优先遍历棋盘算法
// (x, y)为起始位置
// tag是标志标量,每走一步tag+1
bool searchChessBoard(int x, int y, int tag)
{
int x1 = 0;
int y1 = 0;
int flag = 0;
int count = 0;
chess[x][y] = tag;
if (tag == X * Y)
{
//打印棋盘
print();
return true;
}
while (count < 8) {
x1 = x;
y1 = y;
flag = isNextPos(x1, y1, count);
if (flag) {
if (searchChessBoard(x1, y1, tag + 1)) {
return true;
}
}
++count;
}
// 找下一个马可以走的坐标,如果找到flag为1否则为0
chess[x][y] = 0;
return false;
}
int main()
{
for (int i = 0; i < X; ++i) {
for (int j = 0; j < Y; ++j) {
chess[i][j] = 0;
}
}
if (!searchChessBoard(0, 0, 1)) {
printf("失败!\n");
}
getchar();
}