不规则棋盘问题

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84562#problem/K

题目:

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

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

案例:

       Sample Input   

   2 1
   #.
   .#
   4 4
   ...#
   ..#.
   .#..
   #...
   -1 -1

       Sample Output

       2

       1

分析:

            从第一行首格开始,找到#号,把#所在这一列赋值为1,表示后面棋子摆放都不可在这一列,摆放棋子数num加一,继续找到一个符合要求的棋子摆放处,棋子摆放直至num等于需摆放的棋子数,利用DFS找到所有案例...

源代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 int b[10],n,k,C;
 4 char a[10][10];
 5 void dfs(int x,int num)
 6 {
 7     if(k==num) //判断该放置的棋子数是否摆完
 8     {  
 9         C++;//方案成
10         return;
11     }
12     if(n<x) return;//x大于行数n
13     for(int m=0;m<n;m++)
14         if(!b[m]&&a[x][m]=='#')//m列未摆放且x行m列为可摆放处
15         {
16             b[m]=1;//标记m列已经摆放棋子
17             dfs(x+1,num+1);
18             b[m]=0;//清除标记
19         }
20     dfs(x+1,num);//x行不可摆放进行下一行位置摆放判断
21 }
22 int main()
23 {
24     int i;
25     while(scanf("%d%d",&n,&k)&&(n!=-1)&&(k!=-1))
26     {
27         for(i=0;i<n;i++)  
28                scanf("%s",a[i]);
29         memset(b,0,sizeof(b));
30         C=0;//摆放方案
31         dfs(0,0);
32         printf("%d\n",C);
33     }
34     return 0;
35 }

 

posted @ 2015-07-30 15:47  ~瞬间*  阅读(906)  评论(0编辑  收藏  举报