棋盘问题

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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
  1 #include<cstdio>
  2 
  3 #include<cstring>
  4 
  5 #include<algorithm>
  6 
  7 #include<string>
  8 
  9 #include<iostream>
 10 
 11 using namespace std;
 12 
 13 char a[9][9];
 14 
 15 int C[9];
 16 
 17 int sum=0;
 18 
 19 int n,k;
 20 
 21 void dfs(int cnt,int t)
 22 
 23 {
 24 
 25     if(t==k)
 26 
 27     {
 28 
 29         sum++;
 30 
 31     }
 32 
 33     else
 34 
 35     {
 36 
 37         for(int j=1;j<=n;j++)  //包含这一行的情况
 38 
 39         {
 40 
 41             if(a[cnt][j]=='#'&&C[j]==0)
 42 
 43             {
 44 
 45                 C[j]=1;
 46 
 47                 dfs(cnt+1,t+1);
 48 
 49                 C[j]=0;
 50 
 51             }
 52 
 53         }
 54 
 55         if(cnt<n)    //不包含这一行的情况
 56 
 57             dfs(cnt+1,t);
 58 
 59     }
 60 
 61 }
 62 
 63 int main()
 64 
 65 {
 66 
 67  
 68 
 69     while(scanf("%d%d%*c",&n,&k)!=EOF)   //%c 是为了吃掉回车键
 70 
 71     {
 72 
 73         if(n==-1&&k==-1)
 74 
 75             break;
 76 
 77         memset(a,'.',sizeof(a));
 78 
 79         memset(C,0,sizeof(C));
 80 
 81         sum=0;
 82 
 83         for(int i=1;i<=n;i++)
 84 
 85         {
 86 
 87             for(int j=1;j<=n;j++)
 88 
 89             {
 90 
 91                 scanf("%c",&a[i][j]);
 92 
 93             }
 94 
 95             getchar();
 96 
 97         }
 98 
 99         dfs(1,0);
100 
101         printf("%d\n",sum);
102 
103     }
104 
105     return 0;
106 
107 }

 

posted @ 2020-11-01 23:13  BlackSnow  阅读(72)  评论(0)    收藏  举报