题目如下
基本思路:
对于每一行中的每个位置,尝试放置黑皇后:
如果不能放下,则尝试这一行的下一个位置;
如果能放下,尝试放置白皇后:
如果不能放下,则尝试这一行的下一个位置;
如果能放下,开始放下一层的皇后;
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n;//棋盘规模
int main(){
cin >> n;//输入棋盘规模
initPlace(n);//输入棋盘
dfs(1);//尝试第一层
cout << res;//输出
return 0;
}
其中:
initPlace()输入棋盘:
char place[8+1][8+1];//棋盘
void initPlace(int i){
for (int j = 0; j < i; ++j) {
for (int k = 0; k < i; ++k) {
cin >> temp;
//可放置记录为.
if(temp) place[j+1][k+1] = '.';
//不可放置记录为0
else if(!temp) place[j+1][k+1] = '0';
}
}
}
dfs()尝试每一层
//列[列序数],对角线[列序数+行序数],反对角线[列序数-行序数+n]
//值为1则可放置,为0不可放置
vector<int> lH(8+1,1),xH(2*8+1,1),fxH(2*8+1,1);
//黑皇后的列,对角线和反对角线
vector<int> lB(8+1,1),xB(2*8+1,1),fxB(2*8+1,1);
//白皇后的列,对角线和反对角线
void dfs(int i){
if (i == (n+1)) {
//如果进入了第n+1层,说明前面的放好了
res++;
//这里可用代码查看当前棋盘
return;
}
for (int j = 0; j < n; ++j) {
//遍历当前行,尝试放置黑皇后
if((place[i][j+1] == '.')
&& lH[j+1]
&& xH[i+j+1]
&& fxH[j+1-i+n]){
//棋盘可放置并且列、对角线、反对角线允许
place[i][j+1]='H';
//放下棋子,标记为黑皇后(方便查看)
lH[j+1]=xH[i+j+1]=fxH[j+1-i+n]=0;
//列、对角线、反对角线不允许了
for (int k = 0; k < n; ++k) {
//遍历当前行,尝试放置白皇后
if((place[i][k + 1] == '.'
&& lB[k+1]
&& xB[i+ k+ 1]
&& fxB[k+1-i+n]){
//棋盘可放置并且列、对角线、反对角线允许
place[i][k + 1] = 'B';
//标记为白皇后
lB[k + 1]= xB[i + k + 1]= fxB[k + 1 - i + n]=0;
//列、对角线、反对角线不允许了
dfs(i+1);
//进入下一层
place[i][k + 1] = '.';
//拿走白皇后,尝试下一个位置
lB[k + 1]= xB[i + k + 1]= fxB[k + 1 - i + n]=1;
//允许现在的列、对角线、反对角线
}
}
place[i][j+1]='.';
//拿走黑皇后,尝试下一个位置
lH[j+1]=xH[i+j+1]=fxH[j+1-i+n]=1;
//允许现在的列、对角线、反对角线
}
}
}
如果要查看结果
outPlace()输出棋盘
void outPlace(){
//将该函数置于上一个代码块的第14行即可
cout << "-----------" << endl;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cout << place[i+1][j+1];
}
cout << endl;
}
cout << endl;
}