Description
給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少種放法?n小於等於8。
Input
輸入的第一行為一個整數n,表示棋盤的大小。
接下來n行,每行n個0或1的整數,如果一個整數為1,表示對應的位置可以放皇后,如果一個整數為0,表示對應的位置不可以放皇后。
Output
輸出一個整數,表示總共有多少種放法。
Sample Input
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Sample Output
2
1 #include<iostream>
2 #include<cmath>
3 using namespace std; 4 int n; 5 int map[103][103];//存儲棋盤信息
6 int pos_black[103];//存儲黑皇后的行位置
7 int pos_white[103]; //存儲白皇后的行位置
8 int ans; 9 int check_white(int cur){//檢驗白皇后的位置是否符合要求
10 for(int i=1;i<cur;i++){//cur列之前的列都和cur列比較
11 if(pos_white[i]==pos_white[cur]||abs(i-cur)==abs(pos_white[i]-pos_white[cur])) 12 //檢驗是否在同一行或者對角線上
13 return 0; 14 } 15 return 1; 16 } 17 int check_black(int cur){//檢驗黑皇后的位置是否符合要求,和白皇后一樣
18 for(int i=1;i<cur;i++){ 19 if(pos_black[i]==pos_black[cur]||abs(i-cur)==abs(pos_black[i]-pos_black[cur])) 20 return 0; 21 } 22 return 1; 23 } 24 void dfs_white(int cur){//依次放置白皇后
25 if(cur==n+1){//如果已經放置n個了,答案+1
26 ans++; 27 return; 28 } 29 for(int i=1;i<=n;i++){ 30 if(map[i][cur]==0)//看地圖條件是否符合
31 continue; 32 if(pos_black[cur]==i)//看有沒有與黑皇后的位置重合
33 continue; 34 pos_white[cur]=i;//將白皇后放在第i行第cur列
35 if(check_white(cur))//如果剛才放置的這個白皇后符合要切
36 dfs_white(cur+1);//就開始放置下一個白皇后
37 } 38 } 39 void dfs_black(int cur){//依次放置黑皇后
40 if(cur==n+1){//如果已經放置n個了
41 dfs_white(1);//開始放置白皇后
42 return; 43 } 44 for(int i=1;i<=n;i++){ 45 if(map[i][cur]==0)//如果地圖符合條件
46 continue; 47 pos_black[cur]=i;//將黑皇后放在第i行第cur列
48 if(check_black(cur))//如果剛放置的黑皇后符合條件
49 dfs_black(cur+1);//放置下一個黑皇后
50 } 51 } 52 int main(){ 53 cin>>n; 54 for(int i=1;i<=n;i++){ 55 for(int j=1;j<=n;j++){ 56 cin>>map[i][j]; 57 } 58 } 59 dfs_black(1);//開始放置黑皇后
60 cout<<ans;//輸出
61 return 0; 62 }
其實先放置黑皇后和白皇后都一樣,本文以先放置黑皇后為例,
這樣的話,放置白皇后的時候要注意,不能放在黑皇后上。
黑皇后放置完n個后,開始放置白皇后,白皇后放置完n個后,答案數加一,這是一次大循環
這里是一列一列的放,所以同一列一定不會有重復的,
只需判斷 行 和 對角線 是否有重復的就行了
另外,其實哪個叫行哪個叫列都無所謂,你分得清就行