洛谷 P1219 八皇后
题目链接:八皇后
思路
这是一个典型的搜索题目,从前往后依次枚举行数,从第一行开始依次枚举皇后的纵坐标,并判断当前坐标是否满足题目要求,满足题目要求则标记将答案存储,并继续向下枚举下一行。
- 由分析可得每条对角线上的任意一点的横纵坐标满足公式
i - j + n
的值与对角线上其他点的公式值相等,n为棋盘大小。 - 同样由分析可得每条斜对角线上的任意一点的横纵坐标满足公式
i + j
的值与对角线上其他点的公式值相等。
所以此时对于对角线和反对角线上是否存在棋子即可以使用上面的性质来进行判断,而对于行和列上是否存在棋子,其中列可以使用bool数组判断,行可以不用判断,行上不可能存在其他棋子,因为行是搜索中从前往后逐个枚举的。
diagonal数组和back_diagonal数组分别用于判断对角线和反对角线上是否存在棋子,col数组用于判断列上是否存在其他棋子。存在则跳过当前格子,不存在则将对角线和反对角线、列数组中当前格子对应元素标记为true,并搜索下一行的棋子位置。
题解
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
bool diagonal[N], back_diagonal[N], col[N];
int n, ans, res[N];
void dfs(int x) {
if (x > n) {
if (ans < 3) {
for (int i = 1; i <= n; i++) {
cout << res[i] << " ";
}
cout << endl;
}
ans++;
return;
}
for (int j = 1; j <= n; j++) {
if (diagonal[x + j] == true || back_diagonal[x - j + n] == true ||
col[j] == true)
continue;
diagonal[x + j] = true, back_diagonal[x - j + n] = true, col[j] = true,
res[x] = j;
dfs(x + 1);
diagonal[x + j] = false, back_diagonal[x - j + n] = false, col[j] = false,
res[x] = 0;
}
}
int main() {
cin >> n;
dfs(1);
cout << ans << endl;
return 0;
}