问题简述:
国际象棋的棋盘为8*8的方格棋盘。现将”马”放在任意指定的方格中,按照”马”走棋的规则将”马”进行移动。要求每个方格只能进入一次,最终使得”马”走遍棋盘的64个方格。
思路简介:
我们可以根据行走规则,得出在最复杂的情况下,我们可以有8种线路,如图所示:
根据输入的位置,我们对各个情况进行逐一尝试,如果当前选定的位置为合适,则递归进入下一层,再次选择合适的位置;如果有没有下一步合适的地方,则回到上一步,选择另外一种情况。此为一种低效的代码,理论上最多可以有8^64次尝试,速度炒鸡慢,还有一种贪心的优化算法。
基础代码:
#include
#include
#include
#include
#include
#include
#include
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;
}
建议:千万不要去尝试这个方法,电脑会炸的。