问题描述:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
首先能摆放棋子的地方是固定的,在这些固定的位置找到K个位置放棋子问有多少种放法。
数据量很小所以才敢用dfs???
但是这个题不好想,准确的说是不敢下笔,遍历的时间花费太高了。。。写的时候用visit数组表示这一列是不是被使用过,如果没有使用过且这一行的这一列是“#”(可以访问的位置)回溯DFS,回溯法和一般的DFS算法还是不一样的,需要重点学习一下,理解倒是不难,不要忘了判断边界以及这一行没东西最后也要dfs一下
以下是代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,k;
char a[10][10];
int visit[10];
int total,m;
void init()
{
total = 0;
m =0;
memset(visit,0,sizeof(visit));
}
void dfs(int cur)
{
if(k == m)
{
total++;
return;
}
if(cur >= n)
return;
for(int i = 0; i < n ;i++)
{
if(visit[i] == 0 && a[cur][i] == '#')
{
visit[i] = 1;
m++;
dfs(cur+1);
m--;
visit[i] = 0;
}
}
dfs(cur+1);
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF && (n != -1 && k!=-1))
{
init();
for(int i =0; i < n; i++)
{
scanf("%s",a[i]);
}
dfs(0);
printf("%d\n",total);
}
return 0;
}