1月 D - 逃离迷宫 HDU - 1728-复杂dfs的剪枝

Posted -ifrush

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1月 D - 逃离迷宫 HDU - 1728-复杂dfs的剪枝相关的知识,希望对你有一定的参考价值。

    给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗? 
Input
      第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
      第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符.表示该位置为空地,字符*表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x 1, y 1, x 2, y 2 (1 ≤ k ≤ 10, 1 ≤ x 1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能转的弯数,(x 1, y 1), (x 2, y 2)表示两个位置,其中x 1,x 2对应列,y 1, y 2对应行。
Output
      每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
Sample Input

    2
    5 5
    ...**
    *.**.
    .....
    .....
    *....
    1 1 1 1 3
    5 5
    ...**
    *.**.
    .....
    .....
    *....
    2 1 1 1 3

Sample Output

    no
    yes

用dfs遍历走的情况,看可不可以到终点,需要指出的是,在同一个可能面朝的方向不同,需要储存方向这个参数

于是就遍历嘛,上下左右都走一遍,其实我写的时候就知道一定会超时的,但就不想剪枝(小声逼逼

于是就tle了 (手动托脸

剪枝 :如果走了走过的格子,此时可转弯数还少,情况就一定被走过的包含了,考虑了方向:

//turn是剩的可转的弯数,dic是方向参数

if(cnt_t[y][x][dic]<=turn)cnt_t[y][x][dic]=turn;
    else return false;

这次过了,用时200ms

 

但总觉得哪里不对

 

就算方向不同,turn数多的话turn一下就走那个方向了,所以方向并不重要,如果turn小的话直接剪掉就好了

//就像这样...

    if(cnt_t[y][x]<=turn)cnt_t[y][x]=turn;
        else return false;

可等是因为如果之前走过而没到终点的话,不如换个方向再试试

进一步剪了后只用15ms;

ac代码:

#include<cstdio>
#include<cstring>
#define N 1
#define E 2
#define S 3
#define W 4
using namespace std;
int x1,x2,y1,y2,m,n,turns,flag=0,cnt_t[110][110];
char pic[110][110];
bool dfs(int y,int x,int dic,int turn){
    if(cnt_t[y][x]<=turn)cnt_t[y][x]=turn;
    else return false;
    if(flag)return true;
    if(turn<0) return false;
    if(x<1||y<1||x>n||y>m||pic[y][x]==*)return false;//printf("here %d %d
",x,y);
    if(x==x2&&y==y2){flag=1; return true;}
    if(dic==N){
        dfs(y+1,x,N,turn);
        dfs(y,x-1,W,turn-1);
        dfs(y,x+1,E,turn-1);
    }
    else if(dic==E){
        dfs(y,x+1,E,turn);
        dfs(y+1,x,N,turn-1);
        dfs(y-1,x,S,turn-1);
    }
    else if(dic==S){
        dfs(y-1,x,S,turn);
        dfs(y,x-1,W,turn-1);
        dfs(y,x+1,E,turn-1);
    }
    else if(dic==W){
        dfs(y,x-1,W,turn);
        dfs(y+1,x,N,turn-1);
        dfs(y-1,x,S,turn-1);
    }
    return true;
}

int main(){
    int t;
    scanf("%d",&t) ;
    while(t--){
        memset(cnt_t,0,sizeof(cnt_t));
        flag=0;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++)
        scanf("%s",pic[i]+1);
        scanf("%d%d%d%d%d",&turns,&x1,&y1,&x2,&y2);
        dfs(y1,x1,N,turns);
        dfs(y1,x1,E,turns);
        dfs(y1,x1,S,turns);
        dfs(y1,x1,W,turns);
        if(flag)printf("yes
");
        else printf("no
");    
        } 
    return 0;
}

 

以上是关于1月 D - 逃离迷宫 HDU - 1728-复杂dfs的剪枝的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1728 逃离迷宫

逃离迷宫(HDU 1728 BFS)

Hdu 1728 逃离迷宫

HDU 1728 逃离迷宫(DFS||BFS)

hdu 1728 逃离迷宫 bfs记步数

hdu 1728 逃离迷宫 bfs记转向