以骑士身份找到棋盘上所有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个角的路径 #包括 #定义第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个角的路径

我现在运行了大约20分钟的程序,但仍然没有找到解决方案

为什么它花了太长时间,但不确定它是否能让我找到答案,我认为它永远在循环

所以我的问题是,我是否把函数做对了,它最终会给我正确的答案(通往所有三个角落的路径),或者为了得到答案,我需要改变什么


我所说的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