//为了巩固总结自己所学的知识,特意写下此博客,如有不当之处希望大神们多多批评
//
//题目分析:
// 使皇后们不在同一列,同一行,同一斜行。
// 用数组mark[]标记 数组的下标来表示行,数组的值是列,
// 那么斜行又分为两种情况,主对角线,cur+mark[cur],副对角线,cur-mark[cur]
//Example 1 //通过行来查找。所以mark[cur]便是列。
#include <iostream>
using namespace std;
const int maxn=10000;
int n,tot = 0,mark[maxn]={0};
void search(int cur) {
if (cur == n) tot++;
else {
for (int i = 0;i < n; i++) {
int ok = 1;
mark[cur] = i;//尝试把皇后放在第i列
for (int j = 0;j < cur; j++) { //检查是否满足条件
if (mark[cur]==mark[j]||cur+mark[cur]==j+mark[j]||cur-mark[cur]==j-mark[j]) {
ok = 0;
break;
}
}
if (ok) search (cur + 1);
}
}
}
int main() {
cin >> n;
search (0);//从第0个开始
cout << tot << endl;
}
//Example 2 //用二维数组优化
//该方法用一个二维数组vis[0][maxn]标记列,vis[1][maxn]来标记主对角线,vis[2][maxn]来标记副对角线
// vis[0][i]来检查是否该列有皇后,vis[1][cur+i]检查主对角线,vis[2][cur-i+n]来标记副对角线
#include <iostream>
using namespace std;
const int maxn=10000;
int tot=0;
int n;
int p[maxn];
int vis[3][maxn]={0};
void search (int cur) {
if (cur == n) tot++;
else {
for (int i=0;i<n;i++) {
if (!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) {//这里用cur-i+n 的目的是为了防止cur-i<0
p[cur]=i;//用p数组来记录放的位置
vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;
search (cur+1);
vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0;
}
}
}
}
int main() {
cin >> n;
search (0);
cout << tot << endl;
}
//第二种之所以比第一种优化,是因为少了一层循环。