棋盘问题 (八皇后的变形)

题目链接:http://poj.org/problem?id=1321

 

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

Input

输入含有多组测试数据。 
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
当为-1 -1时表示输入结束。 
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

 

思路:

和八皇后的差不多,我们可以从行去考虑也可以从列去考虑。唯一要注意的就是八皇后是每行或者每列必须放一个,而这道题并没有这么规定

 

AC代码:

 1 #include <cstdio>
 2 #include <string>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <string.h>
 6 #include <math.h>
 7 #include <vector>
 8 
 9 using namespace std;
10 
11 int vis[10];
12 char ss[10][10];
13 int ans = 0;
14 int n,k;
15 int cnt = 0;
16 
17 bool check(int i,int j)
18 {
19     if (!vis[j] && ss[i][j] == '#')
20         return true;
21     return false;
22 }
23 
24 
25 void dfs(int row) // 从第row行开始
26 {
27     if (cnt == k) {
28         ans++;
29         return;
30     }
31     if (row == n + 1)
32         return;
33     dfs(row+1);
34     for (int j = 1; j <= n; j++)
35     {
36         if (check(row,j))
37         {
38             vis[j] = 1;
39             cnt++;
40             dfs(row+1);
41             vis[j] = 0;
42             cnt--;
43         }
44     }
45 }
46 
47 int main()
48 {
49 
50     while (cin >> n >> k)
51     {
52         if (n == -1 && k == -1)
53             return 0;
54         for (int i=1;i<=n;i++)
55         {
56             for (int j=1;j<=n;j++)
57             {
58                 cin >> ss[i][j];
59             }
60         }
61         ans = 0,cnt = 0;
62         memset(vis,0, sizeof(vis));
63         dfs(1);
64         printf("%d\n",ans);
65     }
66     return 0;
67 }

 

posted @ 2019-07-12 10:48  _Ackerman  阅读(341)  评论(0编辑  收藏  举报