zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    writeToFile 读写文件问题
    iOS 设置代理过程
    iOS UIView 快速修改 frame,
    touches,motion触摸事件响应
    集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍
    触控(Touch) 、 布局(Layout)
    Autoresizing和AutoLayout
    动画(Animation) 、 高级动画(Core Animation)
    ios开发环境 分支语句 、 循环结构(for) 、 循环结构
    oc内存管理总结(一)
  • 原文地址:https://www.cnblogs.com/zibuyu/p/2644396.html
Copyright © 2011-2022 走看看