描述
给定一个 n*n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、
同一列或同一条斜线(包括正负斜线)上,任意的两个白皇后都不在同一行、同一列或同一条斜线(包括正负斜线)上。问总共有多少种放法?n
小于等于 8。
输入输出格式
输入
输入的第一行为一个整数 n,表示棋盘的大小。接下来 n 行,每行 n 个 0 或 1 的整数,如果一个整数为1,表示对应的位置可以放皇后,如
果一个整数为 0,表示对应的位置不可以放皇后。
输出
输出一个整数,表示总共有多少种放法。
输入输出样例
输入样例 1
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出样例 1
2
输入样例 2
4 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出样例 2
2
解题思路
这题本质和N皇后差不多,只需要找到黑皇后的一种方法后再找白皇后的方法,并使得黑白皇后不在同一格且再加上了一个限制而已。(不会
N皇后的同学可以先去看一看)
题解
1 #include<bits/stdc++.h>
2 using namespace std; 3 int n,num=0; 4 bool l[10001]; 5 bool x[10001]; 6 bool y[10001];//黑皇后的判断 7
8 bool l_[10001]; 9 bool x_[10001]; 10 bool y_[10001];//白皇后的判断 11 bool mp[10001][10001];//公用地图 12 void queenW(int ans); 13 void queenB(int ans)//黑皇后搜索 14 { 15 if(ans==n+1) 16 { 17 queenW(1);//如果找到了一个方法,就搜索白皇后 18 return; 19 } 20 for(int j=1;j<=n;j++) 21 { 22 if(!l[j]&&!x[ans-j]&&!y[ans+j]&&mp[ans][j])//判断 23 { 24 l[j]=true; 25 x[ans-j]=true; 26 y[ans+j]=true; 27 mp[ans][j]=false;//标记并且标记地图 28 queenB(ans+1);//下一个皇后 29 l[j]=false; 30 x[ans-j]=false; 31 y[ans+j]=false; 32 mp[ans][j]=true;//回溯(取消标记) 33 } 34 } 35 return; 36 } 37 void queenW(int ans)//白皇后搜索 38 { 39 if(ans==n+1)//如果找到了,方案加一 40 { 41 num++; 42 } 43 for(int j=1;j<=n;j++) 44 { 45 if(!l_[j]&&!x_[ans-j]&&!y_[ans+j]&&mp[ans][j])//有没有与其他白皇后冲突且这一格没有黑皇后并且能放 46 { 47 l_[j]=true; 48 x_[ans-j]=true; 49 y_[ans+j]=true;//标记 50 queenW(ans+1);//下一个皇后 51 l_[j]=false; 52 x_[ans-j]=false; 53 y_[ans+j]=false;//回溯(取消标记) 54 } 55 } 56 return; 57 } 58 int main() 59 { 60 cin>>n; 61 for(int i=1;i<=n;i++) 62 { 63 for(int j=1;j<=n;j++) 64 { 65 cin>>mp[i][j];//输入限制 66 } 67 } 68 queenB(1);//从黑皇后开始搜 69 cout<<num; 70 return 0; 71 }