hdu1175连连看

深搜+剪枝。。。转折次数不能超过两次。。。直接注释到代码里了。。。

#include<stdio.h>

#include<stdlib.h> 
#include<string.h>
#include<math.h>
#define M 1010
int xs,ys,xe,ye;       
int m,n,q,flag; 
int a[M][M],f[M][M];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void dfs(int x,int y,int t,int d)
{
  int i,nextx,nexty;
  //判断1 
  if(flag==1)  return;    //可以消去 
  if(t>2)      return;    //不能消去 
  if(t==2&&x!=xe&&y!=ye)  return;    //已经转折两次了,可依然不等,故不能消去 
  //判断2
  if(x==xe&&y==ye&&t<=2){       //可以消去 
    flag=1;
    return;                       
  }
  for(i=0;i<4;i++){   
    nextx=x+dir[i][0];
    nexty=y+dir[i][1];                 
    if(nextx<1||nextx>m||nexty<1||nexty>n)   //出界了 
      continue;
    if(nextx==xe&&nexty==ye)   ;
    else if(a[nextx][nexty]!=0)    //非0,走不通 
      continue;
    if(f[nextx][nexty]!=0)   //已走过 
      continue;
    if(d==-1)  ;
    else if(i!=d)  t++;   //方向不同,即转折 
    f[nextx][nexty]=1;
    dfs(nextx,nexty,t,i);
    f[nextx][nexty]=0;
    if(i!=d&&d!=-1)
      t--;
    //printf("t=%d\n",t); 
  }    
}
int main()
{
 int i,j;
 while(scanf("%d %d",&m,&n),!(m==0&&n==0)){
   memset(f,0,sizeof(f)); 
   for(i=1;i<=m;i++)
     for(j=1;j<=n;j++)
       scanf("%d",&a[i][j]);
   scanf("%d",&q);
   for(i=0;i<q;i++){ 
     scanf("%d %d %d %d",&xs,&ys,&xe,&ye);
     if(xs==xe&&ys==ye){       //起点和终点相同 
       printf("NO\n");
       continue;                   
     }
     if(a[xs][ys]!=a[xe][ye]||a[xs][ys]==0||a[xe][ye]==0){  //起点和终点处棋子不等 
       printf("NO\n");
       continue;                                                     
     }
     flag=0;
     f[xs][ys]=1;
     dfs(xs,ys,0,-1);                        //从起点处开始深搜
     f[xs][ys]=0;
     if(flag)  printf("YES\n");
     else      printf("NO\n");
  }                              
 }  
 //system("pause");
 return 0;    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值