題目描述:
給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條斜線(包括正負斜線)上,任意的兩個白皇后都不在同一行、同一列或同一條斜線(包括正負斜線)上。問共有多少种放法?n<=8。
輸入:
第一行輸入一個整數n,表示棋盤的大小。
接下來n行,每行n個0或1的整數。如果一個整數爲1,表示對應的位置可以放皇后,如果一個整數爲0,表示對應的位置不可以放皇后。
輸出:
輸出所有可以按照要求擺放n*n的棋盤,若沒有則不輸出。
注意:數字2表示可以放置黑皇后,數字3表示可以放置白皇后。
最後輸出一個整數,表示總共有多少种放法。
思路:
先擺放完黑皇后,再擺放白皇后。
從第1行到第n行依次擺放皇后。
擺放皇后檢查哪列可以擺放。
注意:只有當mp[][]爲1時纔可以擺放皇后。因爲擺放此皇后之前可能已經擺放了其他皇后。例如,擺放白皇后時,某位已擺放了黑皇后,數字變成了2!
注:其他細節問題均已註釋在代碼中!
代碼如下:
#include<cstdio>
#include<cmath>
int n,ans;
int mp[9][9];
//mp[][]爲0則不可放置皇后,爲1則可放置皇后,爲2則可以放置黑皇后,爲3則可以放置白皇后
bool judge(int x,int y,int k){
//判斷(x,y)位置的k皇后是否與前x-1行的k皇后是否衝突
if(x==1)
return true;
for(int i=1;i<x;++i){
if(mp[i][y]==k)
return false;
for(int j=1;j<=n;++j){
if(abs(x-i)==abs(y-j)&&mp[i][j]==k){
return false;
}
}
}
return true;
}
void dfs(int x,int k){
if(x==n+1&&k==3){ //黑白皇后放置完畢
++ans;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
printf("%-2d",mp[i][j]);
}
printf("\n");
}
printf("\n");
return;
}
if(x==n+1&&k==2){ //黑皇后放置完畢,開始放置白皇后
dfs(1,3);
return;
}
for(int i=1;i<=n;++i){ //對x行k皇后檢查哪列可以放置
if(mp[x][i]==1&&judge(x,i,k)){
mp[x][i]=k;
dfs(x+1,k);
mp[x][i]=1; //因爲是求所有解,所以需要回溯!
}
}
}
int main(){
scanf("%d",&n); //輸入棋盤規格
for(int i=1;i<=n;++i){ //輸入棋盤
for(int j=1;j<=n;++j){
scanf("%d",&mp[i][j]);
}
}
printf("\n");
dfs(1,2);
printf("%d",ans);
return 0;
}
運行結果:
大一小白編寫代碼水平有限,如果對您有幫助,請點贊支持,感謝!
大一小白編寫代碼水平有限,如果對您有幫助,請點贊支持,感謝!
大一小白編寫代碼水平有限,如果對您有幫助,請點贊支持,感謝!
最後,如果你也是一名小白,歡迎添加博主微信:xinglibao465 互相交流進步!感謝!
最後,如果你也是一名小白,歡迎添加博主微信:xinglibao465 互相交流進步!感謝!
最後,如果你也是一名小白,歡迎添加博主微信:xinglibao465 互相交流進步!感謝!