大意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
分析:直接暴力搜索就可以了
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 9; 7 int vis[maxn][maxn]; 8 char mat[maxn][maxn]; 9 int n, k; 10 int vis2[maxn]; 11 int ans; 12 13 void dfs(int i, int num) { 14 // printf("%d %d ", i, num); 15 if(num == k) { 16 ans ++; 17 return; 18 } 19 if(i > n) return ; 20 for(int j = 1; j <= n; j++) { 21 if(vis[i][j] == 0 && !vis2[j]) { 22 vis2[j] = 1; 23 dfs(i + 1, num + 1); 24 vis2[j] = 0; 25 } 26 } 27 dfs(i + 1, num); 28 } 29 30 int main() { 31 while(scanf("%d %d",&n, &k) ) { 32 if(n == -1 && k == -1) break; 33 for(int i = 0; i < n; i++) scanf(" %s", mat[i]); 34 for(int i = 0; i < n; i++) { 35 for(int j = 0; j < n; j++) { 36 if(mat[i][j] == '#') { 37 vis[i + 1][j + 1] = 0; 38 } else vis[i + 1][j + 1] = 1; 39 } 40 } 41 ans = 0; 42 memset(vis2, 0, sizeof(vis2)); 43 dfs(1, 0); 44 printf("%d ", ans); 45 } 46 return 0; 47 }