HDU---2364 Escape【广度优先搜索】
来源:互联网 发布:天津三叶网络 编辑:程序博客网 时间:2024/06/06 13:23
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).
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.
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.
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
29 13##############@..........######.#.#.#.##...........##.#.#.#.#.#.##.#.......#.##.#.#.#.#.#.##...........######.#######4 6#.#####.#.###...@#######
Sample Output
31-1SOURCE:点击打开链接
题意:
自己被困在迷宫中,要求可以前进,左转,右转。然而在遇到能转弯的地方时必须转弯,除非不能转弯或者是转弯才能直行,问至少经过多少步才能走出迷宫。
解析:
略微变形的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;}
阅读全文
1 0
- HDU---2364 Escape【广度优先搜索】
- HDU 1312 广度优先搜索(BFS)
- HDU 1429 广度优先搜索(BFS)
- HDU 1072 Nightmare 广度优先搜索(BFS)
- HDU 1175 广度优先搜索(BFS)
- ()HDU 1548 BFS 广度优先搜索
- hdu 1008 Dogs 广度优先搜索
- HDU 2102 A计划 广度优先搜索
- hdu 1241 Oil Deposits【广度优先搜索】
- hdu 1104 Remainder 【广度优先搜索+数论】
- hdu 1254 推箱子【广度优先搜索】
- hdu 1495 非常可乐【广度优先搜索】
- hdu 2757 Ocean Currents【广度优先搜索】
- BFS--- HDU 1240 Asteroids! 广度优先搜索
- HDU 1072 Nightmare(bfs 广度优先搜索)
- HDU 1401 Solitaire(双向广度优先搜索)
- hdu 2364 Escape【模拟优先队列】【bfs】
- 广度优先搜索算法
- multi_item
- SDUT 2199数据结构实验之链表四:有序链表的归并
- 无限轮播
- Python中如何判断对象是否包含某个属性?
- jQuery的AJAX跨域请求----笔记2017-09-13
- HDU---2364 Escape【广度优先搜索】
- Redis集群批量删除key
- 算法设计课作业系列4——Search a 2D Matrix II
- Mac指令---持续更新
- jQuery中的text(),html(),val()的区别
- Mysql合并某一个字段,解决商品属性查询问题
- 《android开发艺术探索笔记》Part10、Android的消息机制
- squid高性能代理缓存服务器
- 字节流解析json