为什么下面的代码会抛出运行时错误,即使它显示了所需的输出?

时间:2016-12-28 09:35:10

标签: c backtracking

我正在使用回溯来解决8皇后问题。当我在codechef IDE中编译以下代码时,它显示正确的输出,但仍显示运行时错误。

#include <stdio.h>
#include <math.h>
int board[8][8] = { { 0 } };
int demi[8][8] = { { 0 } };
int queen(int a, int b, int c);
void mark(int a, int b);
int main()
{
    int i;
    int b = queen(3, 0, 0);
    for (i = 0; i < 64; i++)
    {
        int x = board[i / 8][i % 8];
        if (x == 1)
            printf(" %d ", x);
        else
        {
            printf(" 0 ");
        }
        if ((i + 1) % 8 == 0)
            printf("\n");
    }
}
int queen(int a, int b, int c)
{
    int t;
    if (c == 8)
        return 1;
    if (a < 0 || a > 7 || b < 0 || b > 7)
        return 0;
    if (!(board[a][b] == 0))
        return 0;
    for (t = 0; t < 64; t++)
    {
        demi[t / 8][t % 8] = board[t / 8][t % 8];
    }
    mark(a, b);
    board[a][b] = 1;
    /*  for(t = 2; t<8; t++)
     {
     if(queen(a+(9-t), b+1, c+1))
     return 1;
     if(queen(a-t, b+1, c+1))
     return 1;
     }*/
    if (queen(a + 7, b + 1, c + 1))
        return 1;
    if (queen(a + 6, b + 1, c + 1))
        return 1;
    if (queen(a + 5, b + 1, c + 1))
        return 1;
    if (queen(a + 4, b + 1, c + 1))
        return 1;
    if (queen(a + 3, b + 1, c + 1))
        return 1;
    if (queen(a + 2, b + 1, c + 1))
        return 1;
    if (queen(a - 2, b + 1, c + 1))
        return 1;
    if (queen(a - 3, b + 1, c + 1))
        return 1;
    if (queen(a - 4, b + 1, c + 1))
        return 1;
    if (queen(a - 5, b + 1, c + 1))
        return 1;
    if (queen(a - 6, b + 1, c + 1))
        return 1;
    if (queen(a - 7, b + 1, c + 1))
        return 1;
    board[a][b] = 0;
    for (t = 0; t < 64; t++) {
        board[t / 8][t % 8] = demi[t / 8][t % 8];
    }
    return 0;
}
void mark(int a, int b)
{
    int i;
    for (i = 0; i < 64; i++)
    {
        int row = i / 8;
        int col = i % 8;
        if (row == a || col == b && !(row == a && col == b))
            board[row][col] = 2;
        if (abs(row - a) == abs(col - b))
            board[row][col] = 2;
    }
}

输出:

enter image description here

此外,如果我将驱动程序语句更改为&#34; queen(0,0,0) or queen(1,0,0)&#34;,结果很正确,最多可达4-5列,但其余列中的结果为0。

enter image description here

我哪里错了?

2 个答案:

答案 0 :(得分:1)

看看你的主要例程:

int main()
{
    ...
    if((i+1)%8==0)
    printf("\n");
}

它应该在成功完成时返回0,但你不会返回任何内容:所以即使你的程序按你想要的那样做,因为你的返回代码是未定义的。

在这种情况下不太可能为0 =&gt;被执行它的引擎看作是错误的执行,它甚至没有尝试进一步分析程序输出。

修复(即使C99使其成为默认值,使用旧的C89进行编译也会产生未定义的结果):

    if((i+1)%8==0)
    printf("\n");
    return 0;
}

正如一些人评论的那样,return 0声明在C99中并不是强制性的。但我认为您的在线平台强制执行严格的C89规则,因此您必须添加它。

答案 1 :(得分:1)

  

此外,如果我将driver语句更改为“ queen(0,0,0) or queen(1,0,0)”,则结果可以正确校正多达4-5列,但其余部分全为0。

有一个很小但有影响力的监督:用于存储demi的递归链中先前实例的板状态的数组queen()是全局定义的;因此,queen()的递归调用将覆盖以前调用的保存状态,从而挫败了回溯。如果demi是在queen()中本地定义的,则您的程序可以正常工作。


关于程序的退出状态,在b末尾的main()值适合在return !b;中使用,因为从queen()返回的值1表示成功。