1217:棋盤問題

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

【輸入】
輸入含有多組測試數據。

每組數據的第一行是兩個正整數n,k,用一個空格隔開,表示了將在一個n×n的矩陣內描述棋盤,以及擺放棋子的數目。(n≤8,k≤n)
當爲−1−1時表示輸入結束。

隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域,. 表示空白區域(數據保證不出現多餘的空白行或者空白列)。

【輸出】
對於每一組數據,給出一行輸出,輸出擺放的方案數目CC(數據保證C<2的31次方)。

【輸入樣例】
2 1
#.
.#
4 4
…#
…#.
.#…
#…
-1 -1

【輸出樣例】
2
1

本題與八皇后類似,但有所區別的就是八皇后要放八個皇后,而這題則是所放的棋子數量是不一定的,即k<=n;所以會存在dfs搜一次n行就有很多種方案,這就要求我們要把n行搜到底(一定要枚舉當前行後的每一行)。

#include<bits/stdc++.h>
using namespace std;
char a[9][9];
int n, k, l[9];
long long ans;
void dfs(int p, int cnt){//p:當前行  cnt:當前已經放的棋子數
	if(cnt == k){
		++ans;
		return ;
	}
	for(int i=p; i<n; i++){//因爲k<=n,每行都放的話,是搜不到底的,所以一定要枚舉當前行之後的每一行
		for(int j=0; j<n; j++){
			if(a[i][j] == '#' && (!l[j]) ){
				l[j] = 1;
				dfs(i+1, cnt+1);//注意是i+1, 我因爲寫成了p+1,導致wa了好幾次
				l[j] = 0;
			}
		}
	}
}
int main(){
	while(cin >> n >> k && n != -1 && k != -1){
		for(int i=0; i<n; i++)
			for(int j=0; j<n; j++)
				cin >> a[i][j];
		memset(l, 0, sizeof(l));
		ans = 0;
		dfs(0, 0);
		cout << ans << endl;
	}
	return 0;
}

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