G - 棋盘问题 POJ - 1321
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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
思路:
深搜,按行搜索,记录已摆放棋子的列,递归,至行末或在此之前棋子数量达到k,则答案++
代码如下:
//Data 2020:03:04 //Time 16ms #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> #include <sstream> #include <string> #include <vector> #include <set> #include <map> #include <list> #include <stack> #include <queue> #include <deque> #include<iomanip> using namespace std; typedef long long LL; typedef long double LD; typedef unsigned long long ULL; const int maxn = 1e4+10; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); int dz[] = {0, 0, 0, 0, 1,-1}; int dx[] = {1,-1, 0, 0, 0, 0}; int dy[] = {0, 0, 1,-1, 0, 0}; struct P { int z, x, y; P(int z = 0, int x = 0, int y = 0): z(z), x(x), y(y) {} }; bool cmp (const void* p1, const void* p2) { return true; } int n, k, ans; char s[10][10]; int vy[10]; int dfs(int i, int m) { if(m == k) return 1; if(i == n) return 0; for(int j = 0; j < n; j++) if(s[i][j] == '#' && !vy[j]) { vy[j] = 1; if(dfs(i+1, m+1)) ans++; vy[j] = 0; } if(k-m < n-i && dfs(i+1, m)) return 1; return 0; } int main() { while(cin >> n >> k && n > 0) { for(int i = 0; i < n; i++) cin >> s[i]; ans = 0; dfs(0, 0); cout << ans << endl; } return 0; }