棋盘问题
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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;
}