棋盘问题

棋盘问题

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

Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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

Sample Output

2
1

分析:
由于题目要求不能同行同列所以先行搜索保证不会同行,
在行中找出可以放棋的位置,并且标记该位置所在的列。
记住在每次在退回去前要将标记的取消。
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=105;
 5 char pic[maxn][maxn];
 6 int k,n,c,d[maxn];
 7 void dfs(int x,int y)
 8 {   
 9           for(int i=0;i<n;i++)
10          { 
11              if(d[i]!=1&&pic[x][i]=='#')
12              {      
13              if(y==1)
14                     c++;
15              else 
16                 {
17                  d[i]=1;           //标记
18                  for(int j=x+1;j<n-y+2;j++)
19                      dfs(j,y-1);
20                  d[i]=0;
21 
22                 }
23                }
24          }
25 }
26 int main()
27 {
28     int i;
29     while(scanf("%d%d",&n,&k)==2&&n!=-1&&k!=-1)
30     { c=0;
31     for( i=0;i<n;i++)
32         cin>>pic[i];
33     memset(d,0,sizeof(d));
34         for(int j=0;j<=n-k;j++)     //控制棋的个数
35             dfs(j,k);
36             cout<<c<<endl;
37     }
38 return 0;
39 }







原文地址:https://www.cnblogs.com/fenhong/p/4687503.html