SCAU18124--N皇后问题
18124 N皇后问题
时间限制:5000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC
Description
有N*N的国际象棋棋盘,要求在上面放N个皇后,要求任意两个皇后不会互杀,有多少种不同的放法?
输入格式
每一个数为T,代表CASE的数量,T<=13 此后,每行一个数N(13>=N>0)
输出格式
每一个CASE,输出对应答案
输入样例
2 4 5
输出样例
2 10
回溯算法
#include <iostream>
#include <vector>
using namespace std;int totalSolutions = 0;void solveNQueens(int row, int n, vector<int>& col, vector<int>& diag1, vector<int>& diag2) {if (row == n) {totalSolutions++;return;}for (int c = 0; c < n; ++c) {if (!col[c] && !diag1[row + c] && !diag2[row - c + n - 1]) {col[c] = diag1[row + c] = diag2[row - c + n - 1] = 1;solveNQueens(row + 1, n, col, diag1, diag2);col[c] = diag1[row + c] = diag2[row - c + n - 1] = 0;}}
}int main() {int T;cin >> T;while (T--) {int n;cin >> n;totalSolutions = 0;vector<int> col(n, 0);//列vector<int> diag1(2 * n - 1, 0);//从左上到右下的对角线vector<int> diag2(2 * n - 1, 0);//从右上到左下的对角线solveNQueens(0, n, col, diag1, diag2);cout << totalSolutions << endl;}return 0;
}
在回溯算法中,我们使用两个数组 diag1
和 diag2
来标记对角线的占用情况:
-
diag1[row + col]
:-
表示副对角线(因为
row + col
是副对角线的唯一标识)。 -
大小为
2n - 1
(因为row + col
的取值范围是[0, 2n-2]
)。
-
-
diag2[row - col + n - 1]
:-
表示主对角线(通过
row - col + n - 1
将负值映射到正索引)。 -
大小为
2n - 1
(因为row - col
的取值范围是[-(n-1), n-1]
)。
-
示例(N=4)
-
主对角线
row - col
的可能值:-3, -2, -1, 0, 1, 2, 3。-
通过
row - col + 3
映射为索引:0, 1, 2, 3, 4, 5, 6。
-
-
副对角线
row + col
的可能值:0, 1, 2, 3, 4, 5, 6(直接作为索引)。