【问题标题】:8 Queens Variation- Number of Arrangements Backtracking Implementation- Wrong Output8 Queens Variation - 安排数回溯实施 - 错误输出
【发布时间】:2015-03-12 04:23:48
【问题描述】:

我正在尝试编写一个程序,在给定初始输入的情况下,它将计算 8X8 棋盘上 8 个皇后的不同排列的数量。出于某种原因,我的测试数据没有给我适当的输出。我想知道你们是否能指出我正确的方向。我没有编译器错误,但我在最后一个数据集上遇到了分段错误。

我尝试过调试,但我想我只是看了很长时间的代码,以至于我开始困惑自己。如果有人可以给我一些帮助,我将不胜感激。谢谢。我认为我的问题要么出在 isSafe 函数中,要么出在我在 solveNQUtil 方法中的终止条件中。

我的测试数据,(每一行是行、列、我的输出和预期结果的单独情况):

r    c    Output      Expected output
1    2       14         8
6    7       8          14
7    8       312        8
8    8       312        4
2    2       4          16
2    4       12         8
1    7       8          8
8    3    Seg Fault     16

我的代码:

#include <iostream>
#include<stdio.h>
using namespace std;
int arrangements = 0;
int column_start = 0;
/* A utility function to print solution */
void printSolution(int board[8][8])
{
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
            if( board[i][j] ) {
                printf(" Q ");
            }else{
                printf(" . ");
            }
            //printf(" %d ", board[i][j]);
        printf("\n");
    }
}
bool isSafe(int board[8][8], int row, int col)
{
    int i, j;
    for (i = 0; i < 8; i++){
        if (board[row][i]){
            return false;
        }
    }
    for (i = row, j = col; i >= 0 && j >= 0; i--, j--){
        if (board[i][j]){
            return false;
        }
    }
    for (i = row, j = col; i < 8 && j < 8; i++, j++){
        if (board[i][j]){
            return false;
        }
    }
    for (i = row, j = col; j >= 0 && i < 8; i++, j--) {
        if (board[i][j]){
            return false;
        }
    }
    for( i = row, j = col; j < 8 && i >= 0; i--, j++){
        if (board[i][j]){
            return false;
        }
    }
    return true;
}
void solveNQUtil(int board[8][8], int queens, int col)
{
    if (queens >= 8){
        printSolution(board);
        cout << "---------------------------------------------" << endl;
        arrangements++;
    }else{
        for (int i = 0; i < 8; i++){
            if ( isSafe(board, i, col) ){
                board[i][col] = 1;
                int tempCol = (col + 1) % 8;
                solveNQUtil(board, queens + 1, tempCol );
                //backtrack
                board[i][col] = 0; 
            }
        }  
    }
}
bool solveNQ(){
    int row = 0;
    int col = 0;
    int board[8][8];
    for(int i = 0; i < 8; i++){
        for(int j = 0; j < 8; j++){
            board[i][j] = 0;
        }
    }
    cin >> row >> col;
    board[row][col] = 1;
    column_start = col;
    solveNQUtil(board, 1, (col + 1) % 8);
    //solveNQUtil(board,0,0);
    if(arrangements == 0){
        printf("Solution does not exist");
        return false;
    }
    return true;
}
int main(){
    solveNQ();
    cout << "Arrangements: " << arrangements << endl;
    return 0;
}

【问题讨论】:

  • 当您使用调试器时,哪些行导致了问题?
  • 我不懂这个游戏的规则。第 1 行和第 1 列在哪里?如果初始值为r=1,c=2,那个位置应该有Q吗?

标签: c++ algorithm backtracking n-queens


【解决方案1】:

只要你的row &lt; 8 and col &lt; 8 你得到的输出是正确的。您给出的预期输出是错误的。

row = 8 or col = 8 数组索引超出范围并尝试将值分配给未分配给数组的一些内存。

  • 如果其他内存是空闲的,它将存储在其中并且不会出现任何错误,但您的输出将是错误的,因为您的第一个皇后在棋盘之外,但您告诉您的 solveNQUtil 棋盘中有皇后.
  • 但如果其他内存已分配给其他内存,则会出现分段错误。

【讨论】:

  • 这似乎做到了。它从零开始到 8。
  • 索引是从 0 到 7,所以我看不出有任何理由去索引 8!
  • @PhamTrung 我也在说同样的话。但是他(提问者)试图获得 row=8 或 col=8 的结果,它在 0 到 7 之外,所以他遇到了分段错误。但是他得到的输出是正确的,其中 row 和 col 小于 8
【解决方案2】:

您将其编程为从零索引开始,因此您只需要将输入减一。所有输出都将符合预期结果。

cin >> row >> col;
row--;
col--;
if (row < 0 || row >= 8 || col < 0 || col >= 8) return false;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 2015-10-07
    • 2011-11-10
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多