骑士的巡回动作n移动,骑士从n(1)移动到(8,8)的移动数量有多少?

时间:2017-09-17 17:23:21

标签: c recursion knights-tour

我一直在努力提高我在C中的递归技能,我遇到了这个问题。我试图解决它,但代码似乎没有正常工作。 例如,骑士有8个选项可以在6次移动中从(1,1)移动到(8,8),在我的代码中,结果完全不同。这个问题询问有多少种方法可以将骑士从(1,1)移动到(8,8)n次移动(用户给出的n)8x8板。这是我的代码:

#include <stdio.h>
#define SIZE 8
//x,y coordinates of the knight.
int knightsTour(int x, int y, int num);
void main() {
int n;
int result;
    do {
        scanf(" %d", &n);
        result = knightsTour(1,1,n);
        printf("%d\n", result);
    } while (n > 0);
}
int knightsTour(int x,int y,int num) {
int result = 0;
int i, j;
if (num == 0) {
    return 0;
}
if (((x > 8) || (y > 8))||((x == 8) && (y == 8))) {
    return 0;
}
for (i = 1; i <= SIZE; i++) {
    for (j = 1; j <= SIZE; j++) {
        if ((i != y) && (j != x) && ((i != y + j) && (j != x + i)) && ((i != y + j) && (j != x - i))
            && ((i != y - j) && (j != x + i)) && ((i != y - j) && (j != x - i))) {
            result += knightsTour(i, j, num - 1) + 1;
        }
    }
}
return result;
}

1 个答案:

答案 0 :(得分:1)

您的代码有几个问题:

  • 在调用recursivev函数时,无条件地向结果添加一个。你应该只计算6次移动后落在h8上的路径,只有在你跳到新位置后才能检查。
  • 当你想找到可能的动作时,检查棋盘上的所有方块都是浪费。你知道骑士的等级和档案,所以你也知道八个可能的动作。你必须小心不要跳板。在函数开头验证排名和文件是否有效更容易。

一种方法是以下递归方法:

  • 等级和档案有效吗?如果没有,请返回0。
  • 我们达到了所需的移动次数吗?如果是这样,如果当前方格是h8,则返回1,否则返回0.
  • 返回骑士可以进行的有效移动次数的总和,以及从当前位置开始的八次可能移动的少一次移动。您无需在此处查看,因为将在函数开头检查移动的有效性。

把它们放在一起:

#include <stdio.h>

#define SIZE 8

int knightsTour(int x, int y, int num)
{
    if (x < 1 || x > SIZE) return 0;
    if (y < 1 || y > SIZE) return 0;

    if (num == 0) return (x == SIZE && y == SIZE);

    return knightsTour(x + 2, y + 1, num - 1)
         + knightsTour(x + 1, y + 2, num - 1)
         + knightsTour(x - 1, y + 2, num - 1)
         + knightsTour(x - 2, y + 1, num - 1)
         + knightsTour(x - 2, y - 1, num - 1)
         + knightsTour(x - 1, y - 2, num - 1)
         + knightsTour(x + 1, y - 2, num - 1)
         + knightsTour(x + 2, y - 1, num - 1);
}

int main(void)
{
    int result = knightsTour(1, 1, 6);

    printf("%d\n", result);
    return 0;
}

此代码很简单,它确定了108种可能的移动。