这个题目把棋子的坐标依次存进数组里,然后再分别用两个数组记录行和列有哪些已经被占用了,之后便从第一个棋子开始深搜即可,深搜函数带两个参数p,
count,p表示从当前第p个棋子开始往下搜,count表示已经放了count个棋子。
把满足条件的位置一次存储起来。再利用回朔搜索,很好;;
#include"stdio.h"
#include"string.h"
char map[100];
int qx[100],qy[100];
int visx[100],visy[100];
int n,m,cnt,k;
void dfs(int p,int count)
{
int i;
if(count==m)
{
cnt++;
return;
}
for(i=p;i<k;i++)
if(!visx[qx[i]]&&!visy[qy[i]])
{
visx[qx[i]]=1;
visy[qy[i]]=1;
dfs(i+1,count+1);
visx[qx[i]]=0;
visy[qy[i]]=0;
}
}
int main()
{
int i;
while(scanf("%d%d",&n,&m),n!=-1&&m!=-1)
{
int j;
cnt=0;k=0;
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
for(i=0;i<n;i++)
{ scanf("%s",map);
for(j=0;j<n;j++)
if(map[j]=='#')
{
qx[k]=i;
qy[k]=j;
k++;
}
}
dfs(0,0);
printf("%d\n",cnt);
}
return 0;
}
#include"stdio.h"
#include"string.h"
char map[100][100];
int n,m,cnt,row[100];
void bfs(int x,int y)//搜索第x行,已经放好了y颗棋子。。
{
int i;
if(y==m)
{
cnt++;
return ;
}
if(x>n)
return ;
for(i=1;i<=n;i++)
{
if(map[x][i]=='#'&&!row[i])//存在位置并且这一列还没访问过。。
{
row[i]=1;
bfs(x+1,y+1);
row[i]=0;
}
}
bfs(x+1,y);
}
int main()
{
int i;
while(scanf("%d%d",&n,&m),n!=-1&&m!=-1)
{
for(i=1;i<=n;i++)
scanf("%s",map[i]+1);
memset(row,0,sizeof(row));
cnt=0;
bfs(1,0);
printf("%d\n",cnt);
}
return 0;
}
这个方法和hdu1045的方法一样。。
#include"stdio.h"
#include"string.h"
char map[100][100];
int row[100],hang[100];
int n,m,cnt;
void dfs(int k,int count)//第k个点,在这个点可以放得总数。。
{
int x,y;
if(count==m)
{
cnt++;
return ;
}
if(k>=n*n)
return ;
x=k/n,y=k%n;
if(map[x][y]=='#'&&!row[y]&&!hang[x])
{
row[y]=1;
hang[x]=1;
dfs(k+1,count+1);
row[y]=0;
hang[x]=0;
}
dfs(k+1,count);//和上面那个方法放的位置不同。。
}
int main()
{
int i;
while(scanf("%d%d",&n,&m),n!=-1&&m!=-1)
{
for(i=0;i<n;i++)
scanf("%s",map[i]);
memset(row,0,sizeof(row));
memset(hang,0,sizeof(hang));
cnt=0;
dfs(0,0);
printf("%d\n",cnt);
}
return 0;
}