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

HDU-1010-Tempter of the Bone

时间:2014-10-04 14:24:56      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:blog   http   io   ar   for   strong   sp   div   art   

题目链接

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

题目意思是讲有一只狗要吃骨头,结果进入了一个迷宫陷阱,迷宫里每走过一个地板费时一秒,该地板 就会在下一秒塌陷,所以你不能在该地板上逗留。迷宫里面有一个门,只能在特定的某一秒才能打开,让狗逃出去。现在题目告诉你迷宫的大小和门打开的时间,问你狗可不可以逃出去,可以就输出YES,否则NO。

 



搜索时要用到的剪枝:

1.如果当前时间即步数(step) >= T 而且还没有找到D点,则剪掉。

2.设当前位置(x, y)到D点(dx, dy)的最短距离为s,到达当前位置(x, y)已经花费时间(步数)step,那么,如果题目要求的时间T - step < s,则剪掉。

3. 对于当前位置(x, y),如果,(T-step-s)是奇数,则剪掉(奇偶剪枝)。

4.如果地图中,可走的点的数目(xnum) < 要求的时间T,则剪掉(路径剪枝)

 

#include<stdio.h>

#include<stdlib.h>

int n,m,ex,ey,t;

int success;

char maze[10][10];

void dfs(int stx,int sty,int dt)

{

    if(stx<=0||stx>n||sty<=0||sty>m)

    return ;

    if(stx==ex&&sty==ey&&dt==t)

    {

        success=1;

        return ;

    }

    int temp=(t-dt)-abs(ex-stx)-abs(ey-sty);

    if(temp<0||temp&1)

    return ;

    if(maze[stx][sty+1]!=‘X‘)

    {

        maze[stx][sty+1]=‘X‘;

        dfs(stx,sty+1,dt+1);

        maze[stx][sty+1]=‘.‘;

    }

    if(maze[stx][sty-1]!=‘X‘)

    {

        maze[stx][sty-1]=‘X‘;

        dfs(stx,sty-1,dt+1);

        maze[stx][sty-1]=‘.‘;

    }

    if(maze[stx+1][sty]!=‘X‘)

    {

        maze[stx+1][sty]=‘X‘;

        dfs(stx+1,sty,dt+1);

        maze[stx+1][sty]=‘.‘;

    }

    if(maze[stx-1][sty]!=‘X‘)

    {

        maze[stx-1][sty]=‘X‘;

        dfs(stx-1,sty,dt+1);

        maze[stx-1][sty]=‘.‘;

    }

}

 

int main(void)

{

    int stx,sty,wall,i,j;

    while(scanf("%d%d%d",&n,&m,&t)==3&&(n+m+t))

    {

        getchar();

        wall=0;

        for(i=1;i<=n;i++)

        {

            for(j=1;j<=m;j++)

            {

                scanf("%c",&maze[i][j]);

                if(maze[i][j]==‘S‘)

                {

                    stx=i;

                    sty=j;

                }

                else if(maze[i][j]==‘D‘)

                {

                    ex=i;

                    ey=j;

                }

                else if(maze[i][j]==‘X‘)

                wall++;

            }

            getchar();

        }

        success=0;

        maze[stx][sty]=‘X‘;

        if(n*m-wall<=t)

        printf("NO\n");

        else

        {

            dfs(stx,sty,0);

            if(success)

            printf("YES\n");

            else

            printf("NO\n");

        }

    }

    return 0;

}

 

 



 

什么是奇偶剪枝?

把矩阵看成如下形式: 
0 1 0 1 0 1 
1 0 1 0 1 0 
0 1 0 1 0 1 
1 0 1 0 1 0 
0 1 0 1 0 1 
从为 0 的格子走一步,必然走向为 1 的格子 。
从为 1 的格子走一步,必然走向为 0 的格子 。
即: 
从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。

所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!

 

比如有一地图:

 

[c-sharp] view plaincopy
 
  1. S...  
  2. ....  
  3. ....  
  4. ....  
  5. ...D  

 

要求从S点到达D点,此时,从S到D的最短距离为s = abs ( dx - sx ) + abs ( dy - sy )。

如果地图中出现了不能经过的障碍物:

 

[c-sharp] view plaincopy
 
  1. S..X  
  2. XX.X  
  3. ...X  
  4. .XXX  
  5. ...D  

 

此时的最短距离s‘ = s + 4,为了绕开障碍,不管偏移几个点,偏移的距离都是最短距离s加上一个偶数距离。

就如同上面说的矩阵,要求你从0走到0,无论你怎么绕,永远都是最短距离(偶数步)加上某个偶数步;要求你从1走到0,永远只能是最短距离(奇数步)加上某个偶数步。

 

 

同时可以搜 奇偶剪枝。 

 

HDU-1010-Tempter of the Bone

标签:blog   http   io   ar   for   strong   sp   div   art   

原文地址:http://www.cnblogs.com/liudehao/p/4005813.html

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