[蓝桥杯]2n皇后问题
题目描述
给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。
现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上
任意的两个白皇后都不在同一行、同一列或同一条对角线上。
问总共有多少种放法?n小于等于8。
输入
输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数
如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出
输出一个整数,表示总共有多少种放法。
样例输入 Copy
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出 Copy
2
代码
我的代码:
#include <iostream>
using namespace std;
int map[10001][10001];
int res[10001][10001];
bool bx[10001];
bool by[10001];
bool bl[10001],br[10001];
bool wx[10001];
bool wy[10001];
bool wl[10001],wr[10001];
int n,sum;
void ouput(){
cout<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<res[i][j]<<' ';
}
cout<<endl;
}
}
void wdfs(int index){
if(index==n+1){
sum++;
}
for(int i=1;i<=n;i++){
if(!wx[index] && !wy[i] && map[index][i]==1){
if(!wl[8+i-index] && !wr[i+index]){
wx[index]=true;
wy[i]=true;
wl[8+i-index]=true;
wr[i+index]=true;
res[index][i]=2;
map[index][i]=0;
wdfs(index+1); //dfs
map[index][i]=1;
wx[index]=false;
wy[i]=false;
wl[8+i-index]=false;
wr[i+index]=false;
res[index][i]=0;
}
}
}
}
void dfs(int index){
//cout<<index;
if(index==n+1){
wdfs(1);
}
for(int i=1;i<=n;i++){
if(!bx[index] && !by[i] && map[index][i]==1){
if(!bl[8+i-index] && !br[i+index]){
bx[index]=true;
by[i]=true;
bl[8+i-index]=true;
br[i+index]=true;
res[index][i]=1;
map[index][i]=0;
dfs(index+1); //dfs
map[index][i]=1;
bx[index]=false;
by[i]=false;
bl[8+i-index]=false;
br[i+index]=false;
res[index][i]=0;
}
}
}
}
int main() {
cin>>n;
sum=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>map[i][j];
res[i][j]=0;
}
}
for(int i=1;i<=n;i++){
bx[i]=false;
by[i]=false;
wx[i]=false;
wy[i]=false;
bl[i]=false;
br[i]=false;
wl[i]=false;
wr[i]=false;
}
dfs(1);
cout<<sum;
return 0;
}
大佬的代码:
#include <iostream>
using namespace std;
int ways = 0;
bool Feasible(int row,int col,int n,int Board[100][100],int color){
if(Board[row][col] == 0 || Board[row][col] == 2)return false;
int color_t = (color == 0) ? 2 : 3;
for(int i = 0;i < n;i++){
if(Board[i][col] == color_t && i != row)return false;
}
//右下
for(int i = 1;i <= n - row && i <= n - col;i++){
if(Board[row+i][col+i] == color_t)return false;
}
for(int i = 1;i <= row && i <= n - col;i++){
if(Board[row-i][col+i] == color_t)return false;
}
for(int i = 1;i <= row && i <= col;i++){
if(Board[row-i][col-i] == color_t)return false;
}
for(int i = 1;i <= n - row && i <= col;i++){
if(Board[row+i][col-i] == color_t)return false;
}
return true;
}
void Queen(int t,int n,int Board[100][100],int row,int col,int color){
if(t == n){
if(color == 0)Queen(0,n,Board,0,0,1);
else{
// cout<<"*"<<endl;
ways++;
return;
}
}
int flag = 0;
int color_t = (color == 0) ? 2 : 3;
for(int i = row;i < n;i++){
if(flag > 0)col = 0;
flag++;
for(int j = col;j < n;j++){
if(Feasible(i,j,n,Board,color)){
Board[i][j] = color_t;
/* cout<<"("<<i<<","<<j<<")"<<endl;
cout<<t<<endl;
cout<<endl;*/
Queen(t+1,n,Board,i+1,0,color);
Board[i][j] = 1;
}
}
}
}
int main(){
int n;
cin>>n;
int Board[100][100];
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cin>>Board[i][j];
}
}
Queen(0,n,Board,0,0,0);
cout<<ways;
return 0;
}