题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84562#problem/K
题意:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给 定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
案例:
input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
output
2
1
思路分析:
从第一行开始,找到#号,把这一列赋值为1,表示后面都不可摆在这一列的#号上,找到一个符合要求的#号,h++,利用DFS找到所有情况。再转到第二行,看是否满足情况。。。。。
源代码如下:
1 #include<iostream> 2 #include<cstring> 3 #define maxn 70 4 using namespace std; 5 int n,k,count,idx[maxn][maxn]; 6 char pic[maxn][maxn]; 7 void dfs(int x,int y,int h) 8 { 9 int i,j,s; 10 for(i=x;i<n;i++) 11 idx[i][y]=1; 12 if(h==k){++count;return;} //满足条件记录 13 for(i=1;i<n-x;i++) 14 for(j=0;j<n;j++) 15 { 16 if(idx[x+i][j]==0&&pic[x+i][j]=='#') 17 { 18 h++; 19 dfs(x+i,j,h); 20 h--; //重新循环,清除记录 21 for(s=x+i;s<n;s++) 22 idx[s][j]=0; //清除标志 23 } 24 } 25 } 26 int main() 27 { 28 int i,j; 29 cin>>n>>k; 30 while(n!=-1) 31 { 32 count=0; 33 for(i=0;i<n;i++) 34 for(j=0;j<n;j++) 35 cin>>pic[i][j]; 36 for(j=0;j<n+1-k;j++) //从第一行开始找出所有满足条件的可能的位置的首位置 37 for(i=0;i<n;i++) 38 { 39 memset(idx,0,sizeof(idx)); //每次重新开始都要清零 40 if(pic[j][i]=='#')dfs(j,i,1); 41 } 42 cout<<count<<endl; 43 cin>>n>>k; 44 } 45 return 0; 46 }