/*
在一张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都无法互相直接攻击得到,
皇后可以直接攻击到她所在的横行,竖列,斜方向上的棋子,现在输入一个整数N,
表示在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都无法互相直接攻击得到的方案数。
例如下面这样的摆法,是4皇后的一个解 (*代表有皇后,-代表没有)
- * - -
- - - *
* - - -
- - * -
*/
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include <iostream>
#include <set>
#include <stack>
void calcQueenPos(int row, int count, std::vector<std::vector<std::string>>& state, std::vector<std::vector<std::vector<std::string>>>& res, std::vector<bool>& cols, std::vector<bool>& diags1, std::vector<bool>& diags2)
{
if(row == count)
{
res.push_back(state);
return;
}
for(int col = 0; col < count; col++)
{
//主副对角线编号,具体可查询"n皇后问题-关于斜线的编号",得编号公式如下
int diag1 = row - col + count - 1;
int diag2 = row + col;
//如果该格子所在的列,主对角线,副对角线都没有放置其它皇后,则在该格子上放置一个皇后
if(!cols[col] && !diags1[diag1] && !diags2[diag2])
{
state[row][col] = "*";
cols[col] = diags1[diag1] = diags2[diag2] = true;
calcQueenPos(row + 1, count, state, res, cols, diags1, diags2);
state[row][col] = "-";
cols[col] = diags1[diag1] = diags2[diag2] = false;
}
}
}
int main()
{
int n;
//输入棋盘大小
std::cin >> n;
//n*n的棋盘,'*'代表皇后,'-'代表空位置
std::vector<std::vector<std::string>> state(n, std::vector<std::string>(n, "-"));
//记录每列是否有皇后
std::vector<bool> cols(n, false);
//记录主对角线上是否有皇后
std::vector<bool> diags1(2*n-1, false);
//记录副对角线上是否有皇后
std::vector<bool> diags2(2*n-1, false);
//结果
std::vector<std::vector<std::vector<std::string>>> res;
calcQueenPos(0, n, state, res, cols, diags1, diags2);
for(auto r1 : res)
{
for(auto r2 : r1)
{
for(auto r3 : r2)
{
std::cout << r3 << " ";
}
std::cout << "\n";
}
std::cout << "\n";
}
return 0;
}
C++ N皇后问题
于 2024-06-17 15:38:19 首次发布