HDOJ_1010 DFS 迷宫 (奇偶剪枝)

这个题目用一般的搜索无法完成,因为题目要求在指定的时间内完成,所以只好一步一步来啦,用DFS解决

但是如果这样结果会超时,网上说是用一种奇偶剪枝的方法来间断搜索时间,下面是剪枝的简单理论,一看就懂:

                          把map看作

                             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 需要奇数步

                       从 0->0 需要偶数步
                       那么设所在位置 (x,y) 与 目标位置 (dx,dy)

                       如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶数步

                       如果abs(x-y)+abs(dx-dy)为奇数,那么说明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇数步

                       理解为 abs(si-sj)+abs(di-dj) 的奇偶性就确定了所需要的步数的奇偶性!!

                       而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时 恰好到达,那么  (ti-step) 与 abs(x-y)+abs(dx-dy) 的奇偶性必须相同

                       因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然为偶数!

 

下面是参考代码:

 

View Code
/* 功能Function Description:     POJ-1010
    开发环境Environment:          vc6.0
    技术特点Technique:
    版本Version:
    作者Author:                   jzjz
    日期Date:                     20120817
    备注Notes:                     迷宫搜索+奇偶剪枝
 */

#include<stdio.h>
#include<math.h>
int time,atx,aty,n,m;
char map[26][26];
bool flag;
void dfs(int x,int y,int t)
{
    if(x<0||x>=n||y<0||y>=m)
        return;
    if(flag==true||(t==0&&x==atx&&aty==y))
    {
        flag=true;
        return;
    }
    int temp=t-abs(x-atx)-abs(y-aty); //剪枝 
    if(temp<0 || temp&1)//奇偶性剪枝   与运算 判断奇偶,偶时才行
        return;
    map[x][y]='X';
    if(map[x+1][y]!='X')
    {
        dfs(x+1,y,t-1);
        if(flag)
           return;
    }
    if(map[x][y+1]!='X')
    {
        dfs(x,y+1,t-1);
        if(flag)
            return;
    }
    if(map[x-1][y]!='X')
    {
        dfs(x-1,y,t-1);
        if(flag)
            return;
    }
    if(map[x][y-1]!='X')
    {
        dfs(x,y-1,t-1);
        if(flag)
            return;
    }
    map[x][y]='.';
}
int main()
{
    int i,j,x,y,wall;
    while(scanf("%d%d%d",&n,&m,&time)&&(n!=0||m!=0||time!=0))
    {
        flag=false;
        wall=0;
        for(i=0;i<n;++i)
        {
            scanf("%s",map[i]);
            for(j=0;j<m;++j)
            {
                if(map[i][j]=='S')
                {
                    x=i;
                    y=j;
                }
                if(map[i][j]=='D')
                {
                    atx=i;
                    aty=j;
                }
                if(map[i][j]=='X')
                    wall++;
            }
        }
        dfs(x,y,time);
        if(n*m-wall<=time)
        {
            printf("NO\n");
            continue;
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
posted @ 2012-08-17 17:17  煮人为乐  阅读(2500)  评论(0编辑  收藏  举报