每天一算法(骑士走棋盘)
2012-12-11 15:58
288 查看
关于骑士走棋盘问题,,一是不了解走棋盘的规则,二是不了解所要使用的那种由J.C. Warnsdorff在1823年提出的解法的意思是什么。。所以只能读代码,,但还真读懂了人家的代码,并自己实现了一下。。
说明
骑士旅游(Knight tour)在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋棋的走法,骑士可以由任一个位置出发,它要如何走完[所有的位置?
解法
骑士的走法,基本上可以使用递回来解决,但是纯綷的递回在维度大时相当没有效率,一个聪明的解法由J.C. Warnsdorff在1823年提出,简单的说,先将最难的位置走完,接下来的路就宽广了,骑士所要走的下一步,「为下一步再选择时,所能走的步数最少的一步。」,使用这个方法,在不使用递回的情况下,可以有较高的机率找出走法(找不到走法的机会也是有的)。
自己实现的代码如下:
int ChessBoard[8][8] = {0};
bool Travel(int FirstX,int FirstY)
{
int movex[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int movey[8] = {1, 2, 2, 1, -1, -2, -2, -1};
ChessBoard[FirstX][FirstY] = 1;
int NextX = FirstX;
int NextY = FirstY;
int NextStepX[8] = {0};
int NextStepY[8] = {0};
int ExitS[8] = {0};
for (int m = 2;m<65;m++)
{
for (int i = 0;i<8;i++)
ExitS[i] = 0;
int Count = 0;
for (int i = 0;i<8;i++)
{
int TemI = NextX + movex[i];
int TemJ = NextY + movey[i];
if (TemI<0||TemI>7||TemJ<0||TemJ>7)
{
continue;
}
if (0 == ChessBoard[TemI][TemJ])
{
NextStepX[Count] = TemI;
NextStepY[Count] = TemJ;
Count++;
}
}
//到这里,Cout表示当前点有几种走法。NextStep中存储各种走法的坐标。
int min = 0;
if (Count<1)
{
return false;
}
if (1 == Count)
{
min = 0;
}
else
{//这一步是为了找到下一次走法中最少种走法的那一步
for (int i = 0;i<Count;i++)
{
for (int j = 0;j<8;j++)
{
int TemI = NextStepX[i]+movex[j];
int TemJ = NextStepY[i]+movey[j];
if (TemI<0||TemI>7||TemJ<0||TemJ>7)
{
continue;
}
if (0 == ChessBoard[TemI][TemJ])
{
ExitS[i]++;
}
}
}
int tem = ExitS[0];
min = 0;
for (int i = 1;i<Count;i++)
{
if (tem > ExitS[i])
{
tem = ExitS[i];
min = i;
}
}
}
NextX = NextStepX[min];
NextY = NextStepY[min];
ChessBoard[NextX][NextY] = m;
}
return true;
}
int main()
{
int startx, starty;
int i, j;
printf("输入起始点:");
scanf("%d %d", &startx, &starty);
if(Travel(startx, starty)) {
printf("游历完成!\n");
}
else {
printf("游历失败!\n");
}
for(i = 0; i < 8; i++) {
for(j = 0; j < 8; j++) {
printf("%2d ", ChessBoard[i][j]);
}
putchar('\n');
}
return 0;
}
说明
骑士旅游(Knight tour)在十八世纪初倍受数学家与拼图迷的注意,它什么时候被提出已不可考,骑士的走法为西洋棋的走法,骑士可以由任一个位置出发,它要如何走完[所有的位置?
解法
骑士的走法,基本上可以使用递回来解决,但是纯綷的递回在维度大时相当没有效率,一个聪明的解法由J.C. Warnsdorff在1823年提出,简单的说,先将最难的位置走完,接下来的路就宽广了,骑士所要走的下一步,「为下一步再选择时,所能走的步数最少的一步。」,使用这个方法,在不使用递回的情况下,可以有较高的机率找出走法(找不到走法的机会也是有的)。
自己实现的代码如下:
int ChessBoard[8][8] = {0};
bool Travel(int FirstX,int FirstY)
{
int movex[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int movey[8] = {1, 2, 2, 1, -1, -2, -2, -1};
ChessBoard[FirstX][FirstY] = 1;
int NextX = FirstX;
int NextY = FirstY;
int NextStepX[8] = {0};
int NextStepY[8] = {0};
int ExitS[8] = {0};
for (int m = 2;m<65;m++)
{
for (int i = 0;i<8;i++)
ExitS[i] = 0;
int Count = 0;
for (int i = 0;i<8;i++)
{
int TemI = NextX + movex[i];
int TemJ = NextY + movey[i];
if (TemI<0||TemI>7||TemJ<0||TemJ>7)
{
continue;
}
if (0 == ChessBoard[TemI][TemJ])
{
NextStepX[Count] = TemI;
NextStepY[Count] = TemJ;
Count++;
}
}
//到这里,Cout表示当前点有几种走法。NextStep中存储各种走法的坐标。
int min = 0;
if (Count<1)
{
return false;
}
if (1 == Count)
{
min = 0;
}
else
{//这一步是为了找到下一次走法中最少种走法的那一步
for (int i = 0;i<Count;i++)
{
for (int j = 0;j<8;j++)
{
int TemI = NextStepX[i]+movex[j];
int TemJ = NextStepY[i]+movey[j];
if (TemI<0||TemI>7||TemJ<0||TemJ>7)
{
continue;
}
if (0 == ChessBoard[TemI][TemJ])
{
ExitS[i]++;
}
}
}
int tem = ExitS[0];
min = 0;
for (int i = 1;i<Count;i++)
{
if (tem > ExitS[i])
{
tem = ExitS[i];
min = i;
}
}
}
NextX = NextStepX[min];
NextY = NextStepY[min];
ChessBoard[NextX][NextY] = m;
}
return true;
}
int main()
{
int startx, starty;
int i, j;
printf("输入起始点:");
scanf("%d %d", &startx, &starty);
if(Travel(startx, starty)) {
printf("游历完成!\n");
}
else {
printf("游历失败!\n");
}
for(i = 0; i < 8; i++) {
for(j = 0; j < 8; j++) {
printf("%2d ", ChessBoard[i][j]);
}
putchar('\n');
}
return 0;
}
相关文章推荐
- 算法训练-骑士走棋盘
- 马踏棋盘算法 [骑士周游问题] --->图
- 小甲鱼数据结构和算法--马踏棋盘(骑士周游问题)
- 在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会
- 在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会
- 马踏棋盘问题(骑士周游问题)及其优化算法java实现
- 骑士走棋盘——C语言经典算法
- Knight Tour 骑士走棋盘算法(附代码)
- 算法思考--------骑士走棋盘(c语言)
- 马踏棋盘算法(骑士周游问题)- 数据结构和算法60
- 马踏棋盘算法(骑士周游问题)- 数据结构和算法60
- 马踏棋盘算法(骑士周游问题)
- 数据结构与算法10:马踏棋盘问题(骑士周游问题)
- 经典游戏算法之骑士走棋盘
- 经典游戏算法之骑士走棋盘
- 每天刷个算法题20160523:骑士巡游的递归转非递归解法
- 数据结构经典算法(7)骑士走棋盘
- 每天一道算法题——丑数
- 每天一个小算法(Heapsort)
- 每天进步一点点------Sobel算子(3)基于彩色图像边缘差分的运动目标检测算法