八皇后问题

八皇后问题_第1张图片

#include <iostream>
#include <cstring>

using namespace std;

const int maxNum = 1005;

// 解的数目
int tot = 0;
// cur:行数 C[cur]:列数
int C[maxNum];
// 皇后总数
int n;

void search1(int cur) {
    // 递归边界
    // 可以输出一个C[n]数组
    // 该数组即为一个解
    if(cur == n) {
        tot++;
    } else {
        for(int i = 0; i < n; i++) {
            int ok = 1;
            // 尝试把第cur行的皇后放在第i列上
            C[cur] = i;
            // 检查是否和前面的皇后有冲突
            for(int j = 0; j < cur; j++) {
                // C[cur] == C[j] 同一列
                // cur - C[cur] == j - C[j] 同一主对角线
                // cur + C[cur] == j + C[j] 同一副对角巷
                if(C[cur] == C[j] || cur - C[cur] == j - C[j]
                        || cur + C[cur] == j + C[j]) {
                    ok = 0;
                    break;
                }
            }
            if(ok) {
                search1(cur + 1);
            }
        }
    }
}


int vis[3][maxNum];

void search2(int cur) {
    // 递归边界
    if(cur == n) {
        tot++;
    } else {
        for(int i = 0; i < n; i++) {
            // 点(cur, i)的列,副对角,主对角是否已有其他皇后
            // 主对角y - x的时候可能为负,所以+n
            // cur 代表行 i 代表列
            if(!vis[0][i] && !vis[1][cur + i] && !vis[2][cur - i + n]) {
                C[cur] = i;
                // 将点(cur,i)的列,副对角,主对角置为已访问
                vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 1;
                // 递归访问
                search2(cur + 1);
                // 回溯
                vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 0;
            }
        }
    }
}


int main() {
    while(cin >> n) {
        // 初始化
        tot = 0;
        memset(vis, 0, sizeof(vis));
// search1(0);
        search2(0);
        cout << "总解数:" << tot << endl;
    }
    return 0;
}

你可能感兴趣的:(ACM,八皇后)