棋盘问题
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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> #include<string.h> using namespace std; int n,k,sum;//注意是全局变量 int G[10][10];//棋盘 int check(int x,int y){ for(int i=1;i<=n;i++){//按行 if(i==y)continue;//这里要注意 if(G[x][i]==1)return false; } for(int j=1;j<=n;j++){ if(j==x)continue; if(G[j][y]==1)return false; } return true; } void dfs(int x,int cnt){ if(cnt==k){//!!这里是等于 sum++;return ; } else if (x > n)return; else for(int i=1;i<=n;i++){//按行遍历 if (G[x][i] == 0) {//!!这里记住要有个判定条件 if(check(x,i)) { G[x][i]=1; dfs(x+1,cnt+1); G[x][i]=0; } } } dfs(x + 1, cnt);//?? return; } int main(){ while(cin>>n>>k){ if(n==-1||k==-1)break; char str[10]; getchar(); memset(G,0,sizeof(G));//初始化G,保证每次输入前都为0 for(int i=1;i<=n;i++){ //memset(str,0,sizeof(str));//初始化 cin.getline(str,10); // cout<<str<<endl; // scanf("%s",str); for(int j=1;j<=n;j++){ if(str[j-1]=='.')G[i][j]=2; else if(str[j-1]=='#')G[i][j]=0; //可放区域 } } /*for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<G[i][j]; } cout<<"\n"; }*/ sum=0; dfs(1,0);//1表示从第一行元素开始(?),0表示cnt cout<<sum<<endl; } }
实例代码
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn = 10; int n, k; int a[maxn][maxn]; int ans; int check(int x, int y) { for (int i = 0; i < n; i++) { if (i == y)continue; if (a[x][i] == 1)return false; } for (int i = 0; i < n; i++) { if (i == x)continue; if (a[i][y] == 1)return false; } return true; } void dfs(int x, int y) { if (y == k) { ans++; return; } if (x >= n)return; for (int i = 0; i < n; i++) { if (a[x][i] == 0) { if (check(x, i)) { a[x][i] = 1; dfs(x + 1, y + 1); a[x][i] = 0; } } } dfs(x + 1, y); return; } int main() { while (scanf("%d%d", &n, &k)!=EOF) { if (n == -1 && k == -1)break; memset(a, 0, sizeof(a)); char op[maxn]; for (int i = 0; i < n; i++) { scanf("%s", op); for (int j = 0; j < n; j++) { if (op[j] == '.') a[i][j] = 2; else a[i][j] = 0; } } ans = 0; dfs(0, 0); printf("%d\n", ans); } return 0; }