棋盘问题(深搜,统计)

棋盘问题

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 48   Accepted Submission(s) : 22
Problem 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
 

 

Source
PKU

题意:

思路:

棋盘问题, 棋子摆放的位置只能是#, 且不能同行和同列. 由于我采用的是按行递增的顺序来搜索的, 因此不可能出现同行的情况, 对于同列的情况, 我设置了一个变量col[], 来保存列的访问状态, 对于之前访问过的列, 棋子是不能再放在这一列上的,true表示该列可以放,false表示该列不可以放DFS(i, j) 代表将第j棵棋子放在i行上。

还是看代码吧,代码里面有注释的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<vector>
 6 
 7 
 8 using namespace std;
 9 bool col[10]={true};//存储第i列可以放棋子吗,true表示可以,false表示不可以
10 bool s[10][10]={false};//s[i][j]==true表示点(i,j)可以存放棋子,s[i][j]==false表示点(i,j)不可以存放棋子
11 int n,k;
12 int number=0;
13 
14 
15 
16 bool DFS(int m,int sum)//深搜函数,DFS(i,j)代表第j个棋子可能放在第i行
17 {
18     if(m<=n+1&&sum==k+1){
19         number++;
20         return true;
21     }
22     if(m==n+1){
23         return false;
24     }
25     for(int i=1;i<=n;i++)
26     {
27         if(s[m][i]&&col[i]){//s[m][i]==true表示第m行第i列可以存放棋子,col[i]==true表示第i列可以存放棋子,一定要注意着我在这WA了好几次
28             col[i]=false;//第i列不再可以存放棋子
29             DFS(m+1,sum+1);
30             col[i]=true;//还原棋盘形状
31         }
32     }
33     DFS(m+1,sum);//第m行不放棋子,定义为空行
34 }
35 
36 
37 int main()
38 {
39 //    freopen("1.txt","r",stdin);
40     while(cin>>n>>k){
41         if(n==k&&n==-1)
42         break;
43         memset(s,false,sizeof(s));
44         for(int i=1;i<=n;i++){
45             for(int j=1;j<=n;j++){
46                 char a;
47                 cin>>a;
48                 if(a=='#')
49                     s[i][j]=true;
50             }
51         }
52         memset(col,true,sizeof(col));
53         number=0;//*******一定要将number置0
54         DFS(1,1);
55         cout<<number<<endl;
56     }
57     return 0;
58 }
View Code

 

posted @ 2013-10-12 17:03  秋心无波  阅读(250)  评论(0编辑  收藏  举报