poj(1321)回朔搜索

这个题目把棋子的坐标依次存进数组里,然后再分别用两个数组记录行和列有哪些已经被占用了,之后便从第一个棋子开始深搜即可,深搜函数带两个参数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; }

 

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值