深度优先遍历加剪枝的经典问题。在递归过程中按行去递归保证了不在同一行,然后使用结构体数组来保存前面行已选定的坐标,在每一行都循环的去选择是哪一列。然后判断和之前的是否在同一列或同一对角线。如果递归到N次了,那么就证明可以有一个方案了。
如何判断在同一对角线:abs(y-y`)==abs(x-x`)
#include <bits/stdc++.h>


using namespace std;

const int maxn = 13;

//记录已经有过的点坐标,方便判断是否在同一对角线
struct Position{
    int x, y;
} ps[maxn];
//方案数
int ans;
int N;
bool yanz(int x, int y) {
    //判断是否在同一列或同一对角线
    for (int i=0;i<x;i++) {
        if (ps[i].y==y||(abs(ps[i].x-x)==abs(ps[i].y-y))) {
            return false;
        }
    }
    return true;
}
//开始深度优先遍历
void dfs(int n) {
    if (n==N) {
//         for (int i=0;i<N;i++) {
//             cout<<ps[i].x<<" "<<ps[i].y<<endl;
//         }
        ans++;
        return ;
    }
    for (int i=0;i<N;i++) {
        if (yanz(n, i)) {
            ps[n].x = n;
            ps[n].y = i;
//             vis[n] = i;
            dfs(n+1);
        } else {
            continue;
        }
    }
    return ;
}


int main() {
    cin>>N;
    dfs(0);
    cout<<ans;
    
    return 0;
}