题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84562#problem/K
题目:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
输入含有多组测试数据,每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目( n <= 8 , k <= n )。当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
案例:
Sample Input
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
2
1
分析:
从第一行首格开始,找到#号,把#所在这一列赋值为1,表示后面棋子摆放都不可在这一列,摆放棋子数num加一,继续找到一个符合要求的棋子摆放处,棋子摆放直至num等于需摆放的棋子数,利用DFS找到所有案例...
源代码:
1 #include<cstdio> 2 #include<cstring> 3 int b[10],n,k,C; 4 char a[10][10]; 5 void dfs(int x,int num) 6 { 7 if(k==num) //判断该放置的棋子数是否摆完 8 { 9 C++;//方案成 10 return; 11 } 12 if(n<x) return;//x大于行数n 13 for(int m=0;m<n;m++) 14 if(!b[m]&&a[x][m]=='#')//m列未摆放且x行m列为可摆放处 15 { 16 b[m]=1;//标记m列已经摆放棋子 17 dfs(x+1,num+1); 18 b[m]=0;//清除标记 19 } 20 dfs(x+1,num);//x行不可摆放进行下一行位置摆放判断 21 } 22 int main() 23 { 24 int i; 25 while(scanf("%d%d",&n,&k)&&(n!=-1)&&(k!=-1)) 26 { 27 for(i=0;i<n;i++) 28 scanf("%s",a[i]); 29 memset(b,0,sizeof(b)); 30 C=0;//摆放方案 31 dfs(0,0); 32 printf("%d ",C); 33 } 34 return 0; 35 }