以骑士身份找到棋盘上所有3个角的路径 #包括 #定义第8面 #定义访问1 #定义未访问的0 #定义FALSE 0 #定义为真!错误的 无效印刷板(内部板[][侧面]); int goHorsie(int板[][侧面]、int x、int y、int step、int cor1、int cor2、int cor3); 内部主(空) { int板[SIDE][SIDE]={未访问}; int=0; 发现=goHorsie(板,0,0,1,0,0,0); 如果(找到) { printf(“是的,有一条从0,0到所有角落的路径!在这里:\n”); 印刷板; } 其他的 { printf(“没有从0,0到所有角落的路径\n”); 印刷板; } getchar(); 返回0; } int goHorsie(int板[][侧面]、int x、int y、int step、int cor1、int cor2、int cor3) { int res=FALSE,check=1; 如果(董事会[x][y]!=没有到访//我们已经在这里了! ||x>=侧面| | y>=侧面| | x
我使用递归找到所有3个角的路径 我现在运行了大约20分钟的程序,但仍然没有找到解决方案 为什么它花了太长时间,但不确定它是否能让我找到答案,我认为它永远在循环 所以我的问题是,我是否把函数做对了,它最终会给我正确的答案(通往所有三个角落的路径),或者为了得到答案,我需要改变什么以骑士身份找到棋盘上所有3个角的路径 #包括 #定义第8面 #定义访问1 #定义未访问的0 #定义FALSE 0 #定义为真!错误的 无效印刷板(内部板[][侧面]); int goHorsie(int板[][侧面]、int x、int y、int step、int cor1、int cor2、int cor3); 内部主(空) { int板[SIDE][SIDE]={未访问}; int=0; 发现=goHorsie(板,0,0,1,0,0,0); 如果(找到) { printf(“是的,有一条从0,0到所有角落的路径!在这里:\n”); 印刷板; } 其他的 { printf(“没有从0,0到所有角落的路径\n”); 印刷板; } getchar(); 返回0; } int goHorsie(int板[][侧面]、int x、int y、int step、int cor1、int cor2、int cor3) { int res=FALSE,check=1; 如果(董事会[x][y]!=没有到访//我们已经在这里了! ||x>=侧面| | y>=侧面| | x,c,recursion,chess,knights-tour,C,Recursion,Chess,Knights Tour,我使用递归找到所有3个角的路径 我现在运行了大约20分钟的程序,但仍然没有找到解决方案 为什么它花了太长时间,但不确定它是否能让我找到答案,我认为它永远在循环 所以我的问题是,我是否把函数做对了,它最终会给我正确的答案(通往所有三个角落的路径),或者为了得到答案,我需要改变什么 我所说的3个角是:右上角、右下角和左下角。可能还有其他错误,但这里有一个: #include <stdio.h> #define SIDE 8 #define VISITED 1 #define NOT
我所说的3个角是:右上角、右下角和左下角。可能还有其他错误,但这里有一个:
#include <stdio.h>
#define SIDE 8
#define VISITED 1
#define NOT_VISITED 0
#define FALSE 0
#define TRUE !FALSE
void printBoard(int board[][SIDE]);
int goHorsie(int board[][SIDE], int x, int y, int step, int cor1, int cor2, int cor3);
int main(void)
{
int board[SIDE][SIDE] = { NOT_VISITED };
int found = 0;
found = goHorsie(board, 0, 0, 1, 0, 0, 0);
if (found)
{
printf("Yes, there is a path from 0,0 through all corners! Here it is:\n");
printBoard(board);
}
else
{
printf("No path from 0,0 through all corners\n");
printBoard(board);
}
getchar();
return 0;
}
int goHorsie(int board[][SIDE], int x, int y, int step, int cor1, int cor2, int cor3)
{
int res = FALSE, check = 1;
if (board[x][y] != NOT_VISITED //We were here already!
|| x >= SIDE || y >= SIDE || x < 0 || y < 0)
{
res = FALSE;
check = 0;
}
if (x == 7 && y == 7)
{
printf("1)found!\n");
cor1 = 1;
}
if (x == 7 && y == 0)
{
printf("2)found!\n");
cor2 = 1;
}
if (x == 0 && y == 7)
{
printf("3)found!\n");
cor3 = 1;
}
if (cor1 == 1 && cor2 == 1 && cor3 == 1)
{
printf("FOUND ALL!\n");
return TRUE;
}
else if(check == 1)
{
board[x][y] = step;
step++;
res =
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3);
if (!res)
{
board[x][y] = NOT_VISITED;
}
}
return res;
}
void printBoard(int board[][SIDE])
{
int i = 0, j = 0;
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
printf("%3d", board[i][j]);
}
printf("\n");
}
}
另一个问题是,在检查您是否已经访问过该角一次之前,请先检查“found”。这将产生一些意想不到的“发现”指纹
这一行:
if (x >= SIDE || y >= SIDE || x < 0 || y < 0 || board[x][y] != NOT_VISITED)
第一行和最后一行使用相同的表达式,即x+1
和y-2
。所以你的代码没有涵盖所有的8个动作。一步两步
我现在运行该程序约20分钟,但仍未找到解决方案。
一旦你修复了上面报告的错误,你就可以尝试一下。。。但如果在20分钟内仍然没有解决方案,也不要感到惊讶
问题是要检查的路径太多了,即使是现代计算机也会花相当多的时间来解决这个问题
考虑这一点:
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3);
总共281.474.976.710.656条路径。。。。好吧,这并不是那么糟糕,因为很多路径在到达第16步之前会停止,因为马离开板或返回到相同的位置。但还是。。。有许多路径需要检查
可以分16步完成吗?它需要20个步骤。。也就是1.152.921.504.606.846.976,或者它甚至需要64个步骤!?8^64个要检查的路径
因此,要找到一个解决方案,您应该以不同于暴力检查的方式思考
通过确定参观拐角的顺序,并对移动方向设置一些限制,我得出了以下结论:
此解决方案表明,您可以在20个动作中访问所有4个角。此答案建立在用户4386427的答案的基础上,将它们组合在一起,以获得完整的解决方案 使用
int-goHorsie(int-board[][侧面]、int-x、int-y、int-step、int-cor1、int-cor2、int-cor3)无论您是否找到了当前递归中的三个角,您总是使用信息的副本。如果您实际上在一个递归调用中找到了一个或两个角点,但不是所有的三个角点,那么一旦递归离开,这些新发现的真值就会丢失。在下一次通话中,您可能会找到丢失的角点,但不会注意到,因为以前找到的角点的信息已丢失
为了保持查找信息,您可以切换到指针参数
int goHorsie(int board[][侧面]、int x、int y、int step、int*cor1、int*cor2、int*cor3)代码>
例如,*cor1=1代码>
为此,您需要在main()中引入相应的可引用变量
int maincor1=0代码>等
并从main()调用
found=goHorsie(板,0,0,1,&maincor1,&maincor2,&maincor3)代码>
从里面还是像
goHorsie(板,x+1,y-2,阶梯,cor1,cor2,cor3)
这是相同的代码,但使用了与以前相同名称的指针变量。您需要演示如何初始化电路板以及如何执行第一个函数call。我不清楚您想查找什么。是a)一条路径让您访问所有三个角点,还是b)三条路径,即每个角点一条路径?向上投票只是因为您的代码的功能太棒了
if (x >= SIDE || y >= SIDE || x < 0 || y < 0 || board[x][y] != NOT_VISITED)
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y + 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 2, y - 1, step, cor1, cor2, cor3) ||
goHorsie(board, x - 1, y + 2, step, cor1, cor2, cor3) ||
goHorsie(board, x + 1, y - 2, step, cor1, cor2, cor3);
step 1: 8 paths
step 2: 8 paths
step 3: 8 paths
...
step 16: 8 paths