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

// 判断当前皇后放置是否合法
int place(int x[], int j, int n) { 
     if (x[j] == j )  
        return 0; // 禁用：位置在棋盘左上到右下对角线上 
    // 判断是否在同一列，或者是否在同一对角线上
    for (int i = 1; i < j; i++) {
        if (x[i] == x[j] || abs(j - i) == abs(x[j] - x[i]))  
            return 0; // 不合法 
    }
    return 1; // 合法
}

// 非递归方式解 N 皇后问题
void nQNoRec(int x[], int n) {
    int j = 1; // j 表示当前放置第 j 个皇后
    for (int i = 1; i <= n; i++) 
        x[i] = 0; 

    while (j >= 1) {
        while (x[j] < n) {
            x[j] = x[j] + 1;
            if (place(x, j, n)) {
                j = j + 1;
                if (j > n) { // 到达叶子节点
                    // 输出解
                    for (int i = 1; i <= n; i++) 
                        printf("%d\t", x[i]); 
                    printf("\n");
                    j = j - 1;
                }
            }
        }
        x[j] = 0; // 回溯时，恢复当前位置的状态
        j = j - 1; // 向上回溯
    }
} 
// 递归方式解 N 皇后问题
void nQueenRec(int x[], int j, int n) {
    if (j > n) { // 搜索到叶子节点  
        // 输出解
        for (int i = 1; i <= n; i++) 
            printf("%d\t", x[i]); 
        printf("\n");
    } else { // 尝试在第 j 行放置皇后 
        for (int i = 1; i <= n; i++) {
            x[j] = i;
            if (place(x, j, n)) 
                nQueenRec(x, j + 1, n);  
        }
    }
}

int main() {
    int n = 6; // 皇后个数
    int x[n + 1]; // 存储每行皇后的位置   

    printf("Recursive solution:\n");
    nQueenRec(x, 1, n); // 递归方式解法
    printf("****************************\n");
    printf("Non-recursive solution:\n");
    nQNoRec(x, n); // 非递归方式解法

    return 0;
}
