1

我正在尝试开发8 个皇后谜题的解决方案,其中 8 个皇后应该放在一个 8x8 棋盘上,这样没有两个皇后可以互相攻击。我可以打印出我的“#”板,但不知道如何在第一个位置放置一个皇后,并使所有水平、垂直和对角线点成为“x”。

这是我到目前为止所拥有的:

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define ROW 8
#define COL 8

// Make the chessboard

int main(int argc, char * argv[])
{
    char board[ROW][COL];
    int i, j;

    for(i = 0; i < ROW; i++)
    {
        for(j = 0; j < COL; j++)
        {
            board[i][j] = '#';
            printf(" %c", board[i][j]);
        }
        printf("\n");
    }
    return 0;
}

// Place queen on first '#'

int placeQueen(char board[ROW][COL])
{
    char queenSpace;
    int i, j;

    for(i = 0; i < ROW; i++)
    {
        for(j = 0; j < COL; j++)
        {
            queenSpace = 'Q';
            board[i][j] = queenSpace;
            printf(" %c", board[1][1]);
        }
        printf("\n");
    }
    return 0;
}

现在的输出在左边,我需要它如右图所示:

# # # # # # # #            Q x x x x x x x
# # # # # # # #            x x # # # # # #
# # # # # # # #            x # x # # # # #
# # # # # # # #            x # # x # # # #
# # # # # # # #            x # # # x # # #
# # # # # # # #            x # # # # x # #
# # # # # # # #            x # # # # # x #
# # # # # # # #            x # # # # # # x

这是我的算法:

  1. 创建一个包含所有“#”的 8x8 数组。
  2. 将皇后放在第一个可用的“#”上。
  3. 将所有水平、垂直和对角方块从皇后位置更改为“x”。
  4. 将另一个皇后放在第一个位置,即“#”。
  5. 将所有水平、垂直和对角方块从新的皇后位置更改为“x”。
  6. 重复步骤 4-5 直到没有更多可用的“#”。
  7. 如果 > 7 个皇后,打印数组并再次运行。
  8. 如果 <= 7 个皇后,则再次运行,但在第二个皇后的位置标有“#”并重复步骤 4-5。
  9. 如果 > 7 个皇后,打印数组并再次运行。
  10. 如果 <= 7 个皇后,重复第 8 步,直到第二个皇后行中不再​​有“#”。
  11. 如果第二个皇后行中没有更多的“#”,则从该行释放内存。
  12. 重复第 8 步,但要换到第 3 个皇后的位置。
  13. 重复步骤 8 - 11,但对于第四个皇后的位置。等等。
  14. 如果没有更多解决方案,请重复步骤 2-13,但在这次第一个皇后所在的位置标记“#”。
  15. 重复第 14 步,直到第一行不再有“#”。

我从来没有使用二维数组做过任何工作或程序,所以任何帮助甚至示例代码都将不胜感激!

4

1 回答 1

1

一些提示。抽象您的主要数据类型:

#define ROW 8
#define COL 8
typedef char t_board[ROW][COL];
#define ItRows(Var) for (int Var = 0; Var < ROW; Var++)
#define ItCols(Var) for (int Var = 0; Var < COL; Var++)
#define EMPTY  '+'
#define QUEEN  'Q'
#define ATTACK '-'

#define bool int
#define true 1
#define false 0

然后您可以简化要对数据类型执行的操作声明,并专注于单个步骤的逻辑:

void init(t_board board) {
   ItRows(r)
       ItCols(c)
           board[r][c] = EMPTY;
}
void show(t_board board) {
   ItRows(r) {
       ItCols(c)
           printf(" %c", board[r][c]);
       printf("\n");
   }
}
void assign(t_board target, const t_board source) {
   ItRows(r)
       ItCols(c)
           target[r][c] = source[r][c];
}
bool reserve(t_board board, int row, int col, char cell) {
    if (board[row][col] == QUEEN)
        return false;
    board[row][col] = cell;
    return true;
}
bool place_queen(t_board board, int row, int col) {
   ItRows(r)
       if (r != row && !reserve(board, r, col, ATTACK))
           return false;
    ItCols(c)
       if (c != col && !reserve(board, row, c, ATTACK))
           return false;

    #define AttackDiag(R, C) \
       for (int r = row + R, c = col + C; r >= 0 && c >= 0 && r < ROW && c < COL; r += R, c += C) \
          if (!reserve(board, r, c, ATTACK)) \
              return false;
    AttackDiag(+1, +1)
    AttackDiag(+1, -1)
    AttackDiag(-1, +1)
    AttackDiag(-1, -1)

    return reserve(board, row, col, QUEEN);
}
int main_queens(int argc, char **argv) {
    t_board b;
    init(b);
    assert(place_queen(b, 3, 2));
    show(b);
    return 0;
}
于 2012-07-26T00:18:36.630 回答