一开始想的时候标记想错了,其实标记只要一组对列的标记就够,这样在行往下的过程中,行每行确定只放一个了,与一般dfs还有一点不同的是,这个有可能出现棋子数不足的情况,这就要求在dfs过程中,需要分放和不放两种,在放的部分中代码再体现出行的标记变换
还有个有点阴的地方是#是可以放的,迷宫题做多了都默认#是不行的了 - -
#include <iostream>
#include <cstring>
using namespace std;
int n,k;
int vis[10];
char m[10][10];
int count = 0;
int total = 0;
void dfs(int x)
{
if(total==k)
{
count++;
return ;
}
if(x>=n)
{
return ;
}
for(int j=0;j<n;j++)//在这一行放
{
if(vis[j]==0&&m[x][j]=='#')//只考虑同一列不能放
{
vis[j] = 1;
total++;
dfs(x+1);
vis[j] = 0;
total--;
}
}
dfs(x+1);// 因为不等额 在这一行直接不放
}
int main(void)
{
while(1)
{
total = 0;
count = 0;
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&k);
if(n==-1&&k==-1)
{
return 0;
}
for(int i=0;i<n;i++)
{
scanf("%s",m[i]);
}
dfs(0);
printf("%d\n",count);
}
}