hdu 1010 Tempter of the Bone 深搜+剪枝

来源:互联网 发布:mac上的软件删不掉 编辑:程序博客网 时间:2024/05/17 04:01
题意:在一个坐标内,给定起点和终点,问能否恰好在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;}


0 0
原创粉丝点击