設計一種算法,列印 N 皇後在 N × N 棋盤上的各種擺法,其中每個皇後都不同行、不同列,也不在對角線上。這裡的“對角線”指的是所有的對角線,不隻是平分整個棋盤的那兩條對角線。
注意:本題相對原題做了擴充
示例:
輸入:4
輸出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解釋: 4 皇後問題存在如下兩個不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/eight-queens-lcci
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#define SIZE 1000
bool PlaceQueen(int posi, int posj, int n, int *queenPositionRow, int *queenPositionCol)
{
if (queenPositionRow[posi] != -1) {
return false;
}
if (queenPositionCol[posj] != -1) {
return false;
}
int j = 1;
for (int i = posi - 1; i >= 0; i--, j++) {
if (posj - j >= 0 && queenPositionRow[i] == posj - j) {
return false;
}
if (posj + j < n && queenPositionRow[i] == posj + j) {
return false;
}
}
j = 1;
for (int i = posi + 1; i < n; i++, j++) {
if (posj - j >= 0 && queenPositionRow[i] == posj - j) {
return false;
}
if (posj + j < n && queenPositionRow[i] == posj + j) {
return false;
}
}
return true;
}
char ** GenerateQueenMap(int n, int *queenPositionRow, int *queenPositionCol)
{
char **map = (char **)malloc(n * sizeof(char *));
for (int i = 0; i < n; i++) {
map[i] = (char *)malloc((n + 1) * sizeof(char));
for (int j = 0; j < n; j++) {
map[i][j] = '.';
}
map[i][queenPositionRow[i]] = 'Q';
map[i][n] = 0;
}
return map;
}
void BackTrack(char*** ret, int i, int n, int* returnSize, int** returnColumnSizes,
int *queenPositionRow, int *queenPositionCol)
{
if (i == n) {
ret[*returnSize] = GenerateQueenMap(n, queenPositionRow, queenPositionCol);
(*returnColumnSizes)[*returnSize] = n;
(*returnSize)++;
return;
}
int j;
for (int j = 0; j < n; j++) {
bool canPlace = PlaceQueen(i, j, n, queenPositionRow, queenPositionCol);
if (canPlace == true) {
queenPositionRow[i] = j;
queenPositionCol[j] = i;
BackTrack(ret, i + 1, n, returnSize, returnColumnSizes,
queenPositionRow, queenPositionCol);
queenPositionRow[i] = -1;
queenPositionCol[j] = -1;
}
}
}
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
char*** solveNQueens(int n, int* returnSize, int** returnColumnSizes)
{
if (returnSize == NULL || returnColumnSizes == NULL) {
return NULL;
}
if (n < 1) {
*returnSize = 0;
return NULL;
}
*returnSize = 0;
char ***ret = (char ***)malloc(SIZE * sizeof(char **));
*returnColumnSizes = (int *)malloc(SIZE * sizeof(int));
int* queenPositionRow = (int*)malloc(n * sizeof(int));
int* queenPositionCol = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
queenPositionRow[i] = -1;
queenPositionCol[i] = -1;
}
BackTrack(ret, 0, n, returnSize, returnColumnSizes, queenPositionRow, queenPositionCol);
free(queenPositionRow);
free(queenPositionCol);
return ret;
}
void testcase1(void)
{
int n = 8;
int returnSize;
int* returnColumnSizes;
char ***ret = solveNQueens(n, &returnSize, &returnColumnSizes);
if (ret != NULL && returnSize > 0) {
printf("*****************************************\n");
for(int m = 0; m < returnSize; m++) {
printf("[\n");
for (int i = 0; i < n; i++) {
printf(" [");
for (int j = 0; j < n; j++) {
printf("%c", ret[m][i][j]);
}
printf("]\n");
}
printf("]\n");
}
}
}
int main()
{
testcase1();
return 0;
}