描述
給定一個 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 }