码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1010 Tempter of the Bone 深搜+剪枝

时间:2015-06-04 13:49:13      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:

题意:在一个坐标内,给定起点和终点,问能否恰好在t时刻到达终点。
以前很少写搜索题,所以看到这个题,就按照普通的深搜写了一下,交上去超时了。后来在网上搜了一下才知道,要剪枝才行。可是,我以前从没写过剪枝,不知道怎么剪,就按照别人的思路往下想。看懂以后,我对剪枝的理解是:对于一些没有必要继续搜索的路径,不再往下深搜,提前返回到上一层。花了半天时间调试代码,终于AC了。
 
 
奇偶剪枝:根据题目,doggie必须在第t秒到达门口。也就是需要走t-1步。设doggie开始的位置为(sx,sy),目标位置为(ex,ey).如果abs(ex-x)+abs(ey-y)为偶数,则abs(ex-x)和abs(ey-y)奇偶性相同,所以需要走偶数步; 

当abs(ex-x)+abs(ey-y)为奇数时,则abs(ex-x)和abs(ey-y)奇偶性不同,到达目标位置就需要走奇数步。先判断奇偶性再搜索可以节省很多时间,不然的话容易超时。t-sum为到达目标位置还需要多少步。因为题目要求doggie必须在第t秒到达门的位置,所以(t-step)和abs(ex-x)+abs(ey-y)的奇偶性必然相同。因此temp=(t-step)-abs(ex-x)+abs(ey-y)必然为偶数。

#include<stdio.h>
#include<string.h>
int flag,sx,sy,ex,ey,num;
int n,m,t,vis[10][10];
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
char map[10][10];
int abs(int p){
    return p>=0?p:-p;
}
void dfs(int x,int y,int sum)
{
    int i,xx,yy;
    if(flag==1) return ;
    if(x==ex&&y==ey&&sum==t)
    {
        flag=1;
        return ;
    }
    int mindis=abs(x-ex)+abs(y-ey);
    if(mindis>t-sum||(mindis+t-sum)%2!=0)
        return;
    for(i=0;i<4;i++)
    {
        xx=x+dx[i];
        yy=y+dy[i];
        if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&map[xx][yy]!='X')
        {
            vis[xx][yy]=1;
            dfs(xx,yy,sum+1);
            vis[xx][yy]=0;
        }
    }
}
int main()
{
    int i,j;
    while(~scanf("%d%d%d",&n,&m,&t)){
        if(n==0&&m==0&&t==0)
            break;
        num=0;
        for(i=0;i<n;i++){
            scanf("%s",map[i]);
            for(j=0;j<m;j++)
            {
                if(map[i][j]=='S')
                {
                    sx=i;
                    sy=j;
                }
                if(map[i][j]=='D'){
                    ex=i;
                    ey=j;
                }
                if(map[i][j]=='X')
                    num++;
            }

        }
        if(n*m - num -1< t)
        {
            printf("NO\n");
            continue;
        }
        flag=0;
        memset(vis,0,sizeof(vis));
       vis[sx][sy] = 1;
           dfs(sx, sy, 0);
        if(flag)
           printf("YES\n");
        else
           printf("NO\n");

    }
    return 0;
}


hdu 1010 Tempter of the Bone 深搜+剪枝

标签:

原文地址:http://blog.csdn.net/a197p/article/details/46359435

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!