/*在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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 */ #include<iostream> using namespace std; int count,n,k,b[8]; char a[8][8]; void dfs(int c,int d) { int i,h; for(i=0;i<n;i++) { if(a[c][i]=='#'&&b[i]==0) //查找到此行的符合条件的位置 { if(d==1) //棋子数是最后一个情况加一 count++; else //棋子数不是最后一个 { b[i]=1; //将上排那一列标记用过了 for(h=c+1;h<=n-d+1;h++) //将剩下那些各行情况都一个个算出,与倒数第五行解释原理大概一样, dfs(h,d-1); b[i]=0; //将标记过的清楚,进行下一轮循环 } } } } int main() { while((cin>>n>>k)&&(n!=-1||k!=-1)) { count=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>a[i][j]; b[i]=0; //b[]标记用某列的# } } for(int i=0;i<=n-k;i++) //到n-k行因为相多余的那些行会重复上面的情况,相当于将上面情况平移下去 dfs(i,k); cout<<count<<endl; } }
K - 1 棋盘问题
最新推荐文章于 2022-04-18 20:43:39 发布