HDU 1175 连连看

来源:互联网 发布:热力学分析软件ipeak 编辑:程序博客网 时间:2024/05/29 03:17

http://acm.hdu.edu.cn/showproblem.php?pid=1175

一个连连看的题目,DFS+剪枝。

代码:

/*HDU 1175 连连看Tips : 搜索+剪枝*/#include<stdio.h>#include<string.h>int n,m,q,tr,tc,sr,sc;int map[1005][1005] ;int vis[1005][1005] ,visn;int dr[4] = {-1,1,0,0} ;int dc[4] = {0,0,-1,1} ;bool flag ;void dfs(int r, int c,int t, int dir){    if(flag)    return ;        //已经找到了 ;    if(t>=3)  return ;          //折线次数超过2次    if(r==tr && c==tc)  {       //找到目标节点        flag = true ;   return ;    }    if(r<1 || r>n || c<1 || c>m || map[r][c]!=0 || vis[r][c]==visn)    return ;         //坐标越界    if(t==2){                   //强剪枝,折线的次数已经到达了两次,以后的操作都是在dir的方向,没有此剪枝为3600+ms,有46ms        if(!(dir==0&&tc==c&&tr<r || dir==1&&tc==c&&tr>r || dir==2&&tr==r&&tc<c || dir==3&&tr==r&&tc>c)){            return ;        }    }    vis[r][c] = visn ;    for(int i=0;i<4;i++){           //四个搜索方向        int rr = r + dr[i] ;        int cc = c + dc[i] ;        if( i==dir )            dfs(rr,cc,t,i);        else            dfs(rr,cc,t+1,i);    }    vis[r][c] = visn - 1 ;}int main(){memset(vis,0,sizeof(vis));visn = 0 ;while(scanf("%d %d",&n,&m) && (n||m)){for(int i=1;i<=n;++i){for(int j=1;j<=m;++j){scanf("%d",&map[i][j]);}}scanf("%d",&q);for(int i=1;i<=q;i++){scanf("%d %d %d %d",&sr,&sc,&tr,&tc);if(sr==tr && sc==tc && map[sr][sc]!=0){     //两个点重合printf("NO\n");continue ;}flag = false ;            if(map[sr][sc]==map[tr][tc] && map[sr][sc]!=0){     //两个相同的点,且不为零visn++ ;  vis[sr][sc] = visn ;for(int i=0;i<4;i++){                    dfs(sr+dr[i],sc+dc[i],0,i);                }if(flag)    printf("YES\n");else    printf("NO\n");}elseprintf("NO\n");}}return 0;}



原创粉丝点击