Description
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
Input
輸入含有多組測試數據。
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨后的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨后的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。
Output
對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。
Sample Input
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
Sample Output
2
1
解題思路:
這個題目的大意是給定一個棋盤和給定我們需要擺放的棋子的數目,然后問我們有幾種擺放方式。首先我們可以明確這是一個深度搜索的題目,與八皇后問題相似。我們建立一個函數DFS用來累計可行的方案數,我們走過一列我們就把它標記下來下次的時候就不可以再擺放在這一列(因為題目要求不可以將棋子擺放在同一行和同一列)
然后就從下一行開始尋找可行的地方,直到我們擺放的棋子數與我們被要求擺放的棋子數相同時,我們就將方案數進行一次++,然后在進行遞歸下去。
程序代碼:
#include<cstdio> #include <iostream> #include<cstring> using namespace std; int n,k,ans; char map[12][12];//棋盤 int vis[12]; int DFS(int i,int cur) { if(cur>=k) // { ans++; //方案數 return 0; } int x,y; for(x=i;x<n;x++) for(y=0;y<n;y++) if(!vis[y] && map[x][y]=='#') { vis[y]=1;//標記 DFS(x+1,cur+1);//遞歸 vis[y]=0; } return 0; } int main() { while(scanf("%d%d",&n,&k)&&n!=-1) { ans=0; memset(map,0,sizeof(map)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) scanf("%s",map[i]); DFS(0,0); printf("%d\n",ans); } return 0; }