HDU---2364 Escape【广度优先搜索】

原创 2017年09月13日 20:55:37
Problem Description
You find yourself trapped in a large rectangular room, made up of large square tiles; some are accessible, others are blocked by obstacles or walls. With a single step, you can move from one tile to another tile if it is horizontally or vertically adjacent (i.e. you cannot move diagonally).
To shake off any people following you, you do not want to move in a straight line. In fact, you want to take a turn at every opportunity, never moving in any single direction longer than strictly necessary. This means that if, for example, you enter a tile from the south, you will turn either left or right, leaving to the west or the east. Only if both directions are blocked, will you move on straight ahead. You never turn around and go back!
Given a map of the room and your starting location, figure out how long it will take you to escape (that is: reach the edge of the room).


 

Input
On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:

a line with two integers separated by a space, h and w (1 <= h, w <= 80), the height and width of the room;

then h lines, each containing w characters, describing the room. Each character is one of . (period; an accessible space), # (a blocked space) or @ (your starting location).
There will be exactly one @ character in each room description.
 

Output
For each test case:

A line with an integer: the minimal number of steps necessary to reach the edge of the room, or -1 if no escape is possible.
 

Sample Input
2 9 13 ############# #@..........# #####.#.#.#.# #...........# #.#.#.#.#.#.# #.#.......#.# #.#.#.#.#.#.# #...........# #####.####### 4 6 #.#### #.#.## #...@# ######
 

Sample Output
31 -1

SOURCE:点击打开链接

题意:

自己被困在迷宫中,要求可以前进,左转,右转。然而在遇到能转弯的地方时必须转弯,除非不能转弯或者是转弯才能直行,问至少经过多少步才能走出迷宫。

解析:

略微变形的BFS,重点在于向左右方向移动。所以用vis数组来记录所处的状态。

代码:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

int h,w;
int vis[85][85][4];    //用来记录所处的位置及状态
int dx[4]= {0,1,0,-1};
int dy[4]= {1,0,-1,0};
char str[85][85];

int bfs(const int x,const int y);

class node
{
public:
    int x;
    int y;
    int step;
    int face;
    node() {};
    node (int x,int y,int step,int face);
};

node::node(int x,int y,int step,int face)
{
    this->x=x;
    this->y=y;
    this->step=step;
    this->face=face;
}

int main(void)
{
    int t,x,y;
    cin>>t;
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        cin>>h>>w;
        for(int i=0; i<h; i++)
            for(int j=0; j<w; j++)
            {
                cin>>str[i][j];
                if(str[i][j]=='@')
                {
                    x=i;
                    y=j;
                }
            }
        cout<<bfs(x,y)<<endl;
    }
    return 0;
}

int bfs(const int x,const int y)
{
    queue<node> q;
    node n(x,y,0,-1);   //在起始位置可以面向任意方向,所以face为-1
    int step,face,nx,ny;
    bool flag;   //用来判断是否只能直行
    vis[x][y][0]=1,vis[x][y][1]=1;   //在起始位置的四种状态都为0,因为在行走的过程中不能经过起始状态
    vis[x][y][2]=1,vis[x][y][3]=1;
    q.push(n);
    while(q.size())
    {
        flag=true;
        n=q.front();
        q.pop();
        if(n.x==0||n.x==h-1||n.y==0||n.y==w-1)
            return n.step;
        for(int i=0; i<4; i++)  //看看能不能转弯
        {
            if(i%2!=n.face%2)  //只能向左右方向走
            {
                nx=n.x+dx[i];
                ny=n.y+dy[i];
                step=n.step+1;
                face=i;
                if(nx>=0&&nx<h&&ny>=0&&ny<w&&str[nx][ny]=='.')
                {
                    flag=false;  //只要左右方向能走就走,不管走没走过
                    if(!vis[nx][ny][face])  //若没有走过,将其加入队列
                    {
                        if(nx==0||nx==h-1||ny==0||ny==w-1)
                            return step;
                        q.push(node(nx,ny,step,face));
                        vis[nx][ny][face]=1;
                    }
                }
            }
        }
        if(flag)  //若不能转弯,则只能直行
        {
            nx=n.x+dx[n.face];
            ny=n.y+dy[n.face];
            step=n.step+1;
            face=n.face;
            if(nx>=0&&nx<h&&ny>=0&&ny<w&&str[nx][ny]=='.'&&!vis[nx][ny][face])
            {
                if(nx==0||nx==h-1||ny==0||ny==w-1)
                    return step;
                q.push(node(nx,ny,step,face));
                vis[nx][ny][face]=1;
            }
        }
    }
    return -1;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

简单的深度优先搜索HDU1045

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目:类似八皇后问题,图中黑框表示墙,空白表示空,可以摆放炮台,炮台可以攻击同排和同列没有墙隔开...
  • leolinsheng
  • leolinsheng
  • 2013年10月10日 15:06
  • 1072

深度优先搜索和广度优先搜索的比较与分析

深度优先搜索和广度优先搜索的比较与分析 一、深度优先搜索和广度优先搜索的深入讨论   (一)深度优先搜索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结...
  • qq328691560
  • qq328691560
  • 2015年08月13日 15:46
  • 3494

[C++]广度优先搜索(BFS)(附例题)

广度优先搜索(BFS)(附例题)问题产生:Isenbaev是国外的一个大牛。现在有许多人要参加ACM ICPC。一共有n个组,每组3个人。同组的3个人都是队友。大家都想知道自己与大牛的最小距离是多少。...
  • stary_yan
  • stary_yan
  • 2016年05月08日 14:16
  • 6571

hdu 2364 Escape【模拟优先队列】【bfs】

Escape Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...
  • hello_sheep
  • hello_sheep
  • 2017年11月12日 12:01
  • 52

hdu 1254 推箱子【广度优先搜索】

推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm...
  • letterwuyu
  • letterwuyu
  • 2014年11月09日 13:50
  • 645

hdu 1104 Remainder 【广度优先搜索+数论】

Remainder Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota...
  • letterwuyu
  • letterwuyu
  • 2014年11月09日 13:35
  • 513

BFS广度优先搜索(4)--hdu2717(poj3278)(基础题)

Catch That C Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%lld & %llu
  • Acmer_Sly
  • Acmer_Sly
  • 2016年09月13日 00:23
  • 297

BFS广度优先搜索(1)--hdu2612(基本模板题)

Find a way                                     Time Limit:1000MS    Memory Limit:32768KB    64bit ...
  • Acmer_Sly
  • Acmer_Sly
  • 2016年09月10日 23:48
  • 637

HDU 2102 A计划(广度优先搜索+数据)

A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm...
  • shao824714565
  • shao824714565
  • 2016年07月30日 11:21
  • 171

Hdu1829 并查集+广度优先搜索

....WA了我N次........ 题目地址:    http://acm.hdu.edu.cn/showproblem.php?pid=1829 题目大意是这样:给你多组"bug"和"bug"...
  • love_clanguage
  • love_clanguage
  • 2012年08月24日 22:38
  • 553
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU---2364 Escape【广度优先搜索】
举报原因:
原因补充:

(最多只允许输入30个字)