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\n",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\n");
        else printf("no\n");
        }
    return 0;
}

原文地址:https://www.cnblogs.com/-ifrush/p/10303196.html

时间: 2024-11-08 17:48:08

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

逃离迷宫HDU - 1728

逃离迷宫HDU - 1728 主要是要记录转弯的次数. 1 #include <iostream> 2 #include <stdio.h> 3 #define ll long long 4 using namespace std; 5 int n,m,gx,gy,p[110][110],k; 6 int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1}; 7 char str[110][110]; 8 bool flag; 9 10 void dfs (in

hdu - 1728逃离迷宫 &amp;&amp; hdu - 1175 连连看 (普通bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1728 这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语. 每个状态除了坐标外还需要记录步数,和方向.还要注意输入格式. 并且每一个点并不是走过了就不能在走,只要到达这个点的时候转向次数少的就可以更新这个点,可以等于.千万注意这个坑. 1 #include <cstdio> 2 #include <cstring> 3 #include <q

hdu 1728 逃离迷宫 (BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14376    Accepted Submission(s): 3458 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方

hdu 1728 逃离迷宫 bfs记转向

题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18702    Accepted Submission(s): 4526 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,g

HDU 1728 逃离迷宫

这道题做的我想哭啊..WA了将近十次了吧 一开始我用数组模拟的队列,后来和老大代码对拍,感觉改的是基本都一模一样了,还是WA 实在没有办法了,改用queue了 题目里的x是列y是行,和代码里的反过来的,要注意! 题目里面说在起点的时候无论朝哪个方向走都不算一次转弯,所以我们将方向和转弯次数都赋值为-1,这样就不用特殊处理了 入队条件,拓展后的转弯次数小于或等于vis数组中记录的最小转弯次数即可入队 输出结果,不要一搜到终点便急着输出,应为可能后面再一次搜到终点的时候转弯次数小于k 因此可以遍历完

HDU 1728 逃离迷宫(BFS)

Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去.令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的.我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可

HDU 1728 逃离迷宫(DFS经典题,比赛手残写废题)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27185    Accepted Submission(s): 6630 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方

hdu 1728 逃离迷宫 bfs记步数

题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18702    Accepted Submission(s): 4526 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,g

hdu 1728 逃离迷宫 (bfs+循环队列)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15248    Accepted Submission(s): 3681 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地