POJ-1321 棋盤問題(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


分析:用深搜判斷...這個問題有點像八皇后問題的改版..使用c數組記錄是否在某列放過子了可以提高效率...因爲不用遍歷了...註釋寫的很清楚了; 
#include<cstdio>
#include<cstring>
#define maxx 10

int c[maxx]; //標記是否用過的列數組 
int n,k;
int num,m; //num是方案數,m是已放的棋子數 
char qipan[maxx][maxx];
void input(){ //輸入 
	for(int i=0;i<n;i++){
			scanf("%s",&qipan[i]);
	}
}
void init(){ //初始化 
	m=0;
	memset(c,0,sizeof(c));
	num=0;
}
void dfs(int t){ //用t代表當前行數 
	if(k==m){ //行數等於棋子數時代表找到一種方案; 
		num++;
		return ;
	}
	if(t>=n) return ;//邊界了 
	for(int i=0;i<n;i++){
		if(qipan[t][i]=='#'&&c[i]==0){
			c[i]=1;
			m++;
			dfs(t+1);
			m--; //遞歸回來的時候減少一個落子數目 
			c[i]=0; 
		}
	}
	dfs(t+1);//本行無可放的位置 
}


int main(){
	while(scanf("%d %d",&n,&k)&&n!=-1&&k!=-1){
		input();
		init();
		dfs(0);
		printf("%d\n",num);
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章