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;
    }
  • 相关阅读:
    洛谷 1339 最短路
    洛谷 1330 封锁阳光大学 图论 二分图染色
    洛谷 1262 间谍网络 Tarjan 图论
    洛谷 1373 dp 小a和uim之大逃离 良心题解
    洛谷 1972 莫队
    洛谷 2158 数论 打表 欧拉函数
    洛谷 1414 数论 分解因数 水题
    蒟蒻的省选复习(不如说是noip普及组复习)————连载中
    关于筛法
    关于整数划分的几类问题
  • 原文地址:https://www.cnblogs.com/zibuyu/p/2644396.html
Copyright © 2011-2022 走看看