棋盘问题
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 #include2 #include 3 #include 4 #include 5 #include 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置054 DFS(1,1);55 cout< <