深度优先遍历加剪枝的经典问题。在递归过程中按行去递归保证了不在同一行,然后使用结构体数组来保存前面行已选定的坐标,在每一行都循环的去选择是哪一列。然后判断和之前的是否在同一列或同一对角线。如果递归到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; }