hdu1010 Tempter of the Bone(dfs)

来源:互联网 发布:电瓶车速度测试软件 编辑:程序博客网 时间:2024/05/01 23:36

   copy from:http://blog.csdn.net/luomingjun12315/article/details/43113807


 这一题的dfs算是简单,但是本题难就难在剪枝。不剪枝的dfs也能过但是也稍微做一点优化,才能AC。但是如果使用 奇偶剪枝 的话效果就比优化明显多了

虽然几次优化可以达到405MS(感觉应该是极致了,划线的为奇偶剪枝),但是不如奇偶剪枝一剪就到202MS。
现在我来介绍下奇偶剪枝:
      

首先举个例子,有如下4*4的迷宫,'.'为可走路段,'X'为障碍不可通过

S...
....
....
...D

从S到D的最短距离为两点横坐标差的绝对值+两点纵坐标差的绝对值 = abs(Sx - Dx) + abs(Sy - Dy) = 6,这个应该是显而易见的。

遇到有障碍的时候呢

S.XX
X.XX
...X
...D

你会发现不管你怎么绕路,最后从S到达D的距离都是最短距离+一个偶数,这个是可以证明的

而我们知道:

奇数 + 偶数 = 奇数
偶数 + 偶数 = 偶数

因此不管有多少障碍,不管绕多少路,只要能到达目的地,走过的距离必然是跟最短距离的奇偶性是一致的。

所以,这样对于一部分不可行的方案几乎就是瞬间搞定

下面直接上代码了:


#include <iostream>#include <stdlib.h>#include <cstring>using namespace std;char maze[10][10];bool dfs(int x, int y, int T){    // 剩一步时即可判断是否为出口,找到返回true    if (T == 1){        if (maze[x-1][y] == 'D') return true;        if (maze[x+1][y] == 'D') return true;        if (maze[x][y-1] == 'D') return true;        if (maze[x][y+1] == 'D') return true;        return false;    }    else{        // 标记走过        maze[x][y] = 'X';        // 深度优先搜索        if (maze[x-1][y] == '.' && dfs(x-1, y, T-1)) return true;        if (maze[x+1][y] == '.' && dfs(x+1, y, T-1)) return true;        if (maze[x][y-1] == '.' && dfs(x, y-1, T-1)) return true;        if (maze[x][y+1] == '.' && dfs(x, y+1, T-1)) return true;        // 还原走过        maze[x][y] = '.';        return false;    }}int main(){    int sx,sy,gx,gy;    int N,M,T;    while(cin>>N>>M>>T,T){        memset(maze,'X',sizeof(maze));        for(int i=0;i<N;i++){            for(int j=0;j<M;j++){                cin>>maze[i][j];                if(maze[i][j]=='S')                    sx=i,sy=j;                else if(maze[i][j]=='D')                    gx=i,gy=j;            }        }        if( ( abs(sx-gx)+abs(sy-gy) - T ) & 1 )        //奇偶剪枝            cout<<"NO"<<endl;        else{            if(dfs(sx,sy,T))                cout<<"YES"<<endl;            else                cout<<"NO"<<endl;        }    }    return 0;}


0 0
原创粉丝点击