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;
}

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