題目連結:八皇后
思路
這是一個典型的搜尋題目,從前往後依次列舉行數,從第一行開始依次列舉皇后的縱座標,並判斷當前座標是否滿足題目要求,滿足題目要求則標記將答案儲存,並繼續向下列舉下一行。
- 由分析可得每條對角線上的任意一點的橫縱座標滿足公式
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;
}