POJ 1321 棋盘问题

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

题目

分析:n代表的是棋盘的大小,不等于棋盘区域的形状。按照每一行搜索,当摆放数为k时计数加一返回,否则如果满足条件则继续搜索下一行。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <queue>
 6 #include <cmath>
 7 #include <stack>
 8 #include <set>
 9 #include <map>
10 #include <algorithm>
11 using namespace std;
12 #define ll long long
13 #define inf 0x3f3f3f3f
14 char g[10][10];
15 bool v[10];
16 int n,k,s;
17 void dfs(int x,int num)//到第x行之前已摆放num个
18 {
19     int i,j;
20     if(num==k)
21     {
22         s++;
23         return ;
24     }
25     if(k-num>n+1-x) return ;//剪枝,如果剩余要摆放的棋子>剩余行数,返回。x从1开始故为n-x+1
26     for(i=x;i<=n;i++)//搜索x-n行的可摆放情况
27     {
28         for(j=0;j<n;j++)
29         {
30             if(g[i][j]=='#'&&!v[j])
31             {
32                 v[j]=1;
33                 dfs(i+1,num+1);
34                 v[j]=0;
35             }
36             //搜索第i行下一个可摆棋子的列
37         }
38         //第i行摆棋子的情况递归搜索完,继续搜索第i行不摆棋子的情况
39     }
40 }
41 int main()
42 {
43     int i,j;
44     while(~scanf("%d %d",&n,&k))
45     {
46         if(n==-1&&k==-1) break;
47         s=0;
48         memset(v,0,sizeof v);
49         for(i=1;i<=n;i++)//行下标从1开始,列从0开始
50             scanf("%s",g[i]);
51         dfs(1,0);
52         printf("%d\n",s);
53     }
54     return 0;
55 }

 

posted @ 2016-10-16 21:46  Nautilus1s  阅读(104)  评论(0编辑  收藏  举报