1. 程式人生 > >POJ1321棋盤問題(DFS)(簡單搜尋)

POJ1321棋盤問題(DFS)(簡單搜尋)

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。

Input

輸入含有多組測試資料。  每組資料的第一行是兩個正整數,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

AC程式碼:

#include<stdio.h>
#include<string.h>

char mp[10][10];
int book[10],sum,n,k;

void dfs(int x,int cnt)//第x行 放了cnt個棋子 
{
	if(cnt==k)//放夠k個棋子則結束 
	{
		sum++;
		return;
	}
	if(x>=n) return;//沒放夠k個棋子但是棋盤已經遍歷完則結束 
	for(int i=0;i<n;i++)//對x行的每一列遍歷 
	{
		if(mp[x][i]=='#'&&book[i]==0)//如果第i列已被標記則不能放 
		{
			book[i]=1;
			dfs(x+1,cnt+1);//在x行能放棋 
			book[i]=0;//深搜不要忘記取消標記 
		}
	}
	dfs(x+1,cnt);//如果在x行沒有放棋 繼續遍歷下一行 
	return;
}

int main()
{
	while(~scanf("%d%d",&n,&k))
	{
		if(n==-1&&k==-1) break;
		for(int i=0;i<n;i++)
		{
			scanf("%s",mp[i]);
		}
		memset(book,0,sizeof(book));
		sum=0;
		dfs(0,0);
		printf("%d\n",sum);
	}
	return 0;
}