Description

The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombies, chainsaw-wielding psychopaths, hippies, and other terrors on their quest to find the exit.
One popular maze-walking strategy guarantees that the visitor will eventually find the exit. Simply choose either the right or left wall, and follow it. Of course, there's no guarantee which strategy (left or right) will be better, and the path taken is seldom the most efficient. (It also doesn't work on mazes with exits that are not on the edge; those types of mazes are not represented in this problem.)
As the proprieter of a cornfield that is about to be converted into a maze, you'd like to have a computer program that can determine the left and right-hand paths along with the shortest path so that you can figure out which layout has the best chance of confounding visitors.

Input

Input to this problem will begin with a line containing a single integer n indicating the number of mazes. Each maze will consist of one line with a width, w, and height, h (3 <= w, h <= 40), followed by h lines of w characters each that represent the maze layout. Walls are represented by hash marks ('#'), empty space by periods ('.'), the start by an 'S' and the exit by an 'E'.
Exactly one 'S' and one 'E' will be present in the maze, and they will always be located along one of the maze edges and never in a corner. The maze will be fully enclosed by walls ('#'), with the only openings being the 'S' and 'E'. The 'S' and 'E' will also be separated by at least one wall ('#').
You may assume that the maze exit is always reachable from the start point.

Output

For each maze in the input, output on a single line the number of (not necessarily unique) squares that a person would visit (including the 'S' and 'E') for (in order) the left, right, and shortest paths, separated by a single space each. Movement from one square to another is only allowed in the horizontal or vertical direction; movement along the diagonals is not allowed.

Sample Input

2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########

Sample Output

37 5 5
17 17 9
 #include <cstdio>
#include <cstring>
#include <queue>
using namespace std; struct node
{
int x, y;
int step;
}start,end; int T, w, h, L_step, R_step, step; int dir[][]={-,,,-,,,,}; char map[][], *p; //左边、右边优先搜索都不是找最短路,因此走过的路可以再走,无需标记走过的格
bool DFS_Left(int x,int y,int d)
{
int _d, _dx, _dy;
if(map[x][y]=='E')
{
return true;
} L_step++; //根据上一次走的方向,用公式推出下一次要走的方向 //往左走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Left(_dx,_dy,_d))
return true;
} //往原始方向走
_d = d;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Left(_dx,_dy,_d))
return true;
} //往右边走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Left(_dx,_dy,_d))
return true;
} //往回走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Left(_dx,_dy,_d))
return true;
} L_step--;
return false;
} bool DFS_Right(int x,int y,int d)
{
int _d, _dx, _dy;
if(map[x][y]=='E')
{
return true;
} R_step++; //根据上一次走的方向,用公式推出下一次要走的方向 //往右走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Right(_dx,_dy,_d))
return true;
} //往原始方向走
_d = d;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Right(_dx,_dy,_d))
return true;
} //往左边走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Right(_dx,_dy,_d))
return true;
} //往回走
_d = (d+)%;
_dx = x + dir[_d][];
_dy = y + dir[_d][];
if(map[_dx][_dy]!='#' && _dx>= && _dx<h && _dy>= && _dy<w)
{
if(DFS_Right(_dx,_dy,_d))
return true;
} R_step--;
return false;
} //寻找最短路只能用BFS
void BFS()
{
node temp,next;
queue<node>p;
p.push(start);
while(!p.empty())
{
temp=p.front();
p.pop(); if(temp.x==end.x && temp.y==end.y)
{
step = temp.step;
break;
} next.step = temp.step + ;
for(int i=;i<;i++)
{
next.x = temp.x + dir[i][];
next.y = temp.y + dir[i][];
if(map[next.x][next.y]!='#' && next.x>= && next.x<h && next.y>= && next.y<w)
{
//BFS中在原始地图中记录走过的路径,会把结束标记给覆盖掉,所以要预先存储
//终点坐标,或者另开一个数组记录路径
map[next.x][next.y]='#';
p.push(next);
}
}
}
return;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&w,&h);
for(int i=;i<h;i++)
{
scanf("%s",map[i]); //获取起点坐标
p=strchr(map[i],'S');
if(p!=NULL)
{
start.x=i;
start.y=p-map[i];
} p=strchr(map[i],'E'); if(p!=NULL)
{
end.x=i;
end.y=p-map[i];
}
} L_step=R_step=; start.step=; DFS_Left(start.x,start.y,);
DFS_Right(start.x,start.y,);
BFS();
printf("%d %d %d\n",L_step,R_step,step);
}
return ;
}

POJ_3083——贴左右墙DFS,最短路径BFS的更多相关文章

  1. 图论相关知识(DFS、BFS、拓扑排序、最小代价生成树、最短路径)

    图的存储 假设是n点m边的图: 邻接矩阵:很简单,但是遍历图的时间复杂度和空间复杂度都为n^2,不适合数据量大的情况 邻接表:略微复杂一丢丢,空间复杂度n+m,遍历图的时间复杂度为m,适用情况更广 前 ...

  2. Clone Graph leetcode java(DFS and BFS 基础)

    题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. ...

  3. 在DFS和BFS中一般情况可以不用vis[][]数组标记

    开始学dfs 与bfs 时一直喜欢用vis[][]来标记有没有访问过, 现在我觉得没有必要用vis[][]标记了 看代码 用'#'表示墙,'.'表示道路 if(所有情况都满足){ map[i][j]= ...

  4. 列出连通集(DFS及BFS遍历图) -- 数据结构

    题目: 7-1 列出连通集 (30 分) 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递 ...

  5. DFS与BFS题解:[kaungbin]带你飞 简单搜索 解题报告

    DFS and  BFS 在解题前我们还是大致讲一下dfs与bfs的.(我感觉我不会bfs) 1.DFS dfs(深度优先算法) 正如其名,dfs是相当的深度,不走到最深处绝不回头的那种. 深度优先搜 ...

  6. 数据结构(12) -- 图的邻接矩阵的DFS和BFS

    //////////////////////////////////////////////////////// //图的邻接矩阵的DFS和BFS ////////////////////////// ...

  7. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  8. 图论中DFS与BFS的区别、用法、详解…

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  9. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

随机推荐

  1. TCP服务器:多进程

    代码: server: #include<netinet/in.h> #include<sys/socket.h> #include<sys/wait.h> #in ...

  2. XTU1199:Number Game

    题目描写叙述 给你一个有N个数的集合S和一个数X,推断是否存在S的一个子集,子集里的数的最小公倍数正好是X. 输入 第一行是数据组数T. 接下来有多组数据,每组数据包括两行: 第一行有2个数N和X,1 ...

  3. MM32初识(兼容STM32)

    MM32初识(兼容STM32) 资源与开发环境 keil 5.0 MM32 miniboard 提要 stm32入门(MM32兼容) 点亮LED思路简介 GPIO配置 stm32寄存器理解与操作步骤 ...

  4. 线段树---HDU1394Minimum Inversion Number

    此题和上题略有不同,但是大体差不多,不过要把题意转换过来,题目大体意思为, 输入n, 也就是n个数,这些数为0 - (n-1), 这些数刚开始给定输入的顺序, 然后求他的逆序数,然后接着把第一个移到这 ...

  5. MediaPlayer+SurfaceView 视频播放 示例

    SurfaceView的原理         SurfaceView在视频播放中起到显示画面的作用,而视频的播放主要通过MediaPlayer来控制.         SurfaceView 允许我们 ...

  6. 新闻源图片放到js里

    例子:http://www.s1979.com/jkys/20141209/2547965.html <script type="text/javascript" src=& ...

  7. Java请求参数类QueryParameter

    import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; /** * 请求 ...

  8. MSSQL 简单练习回顾

    这段时间,报了浦软培训的.NET,现在整理回顾下,算是个小小总结吧 为了便于操作,我没有在多个数据库间切换数据库实例,以一个总的数据库实例 test_demo为源进行的相关操作,代码的注释根据我的理解 ...

  9. 【转】解析JDK 7的动态类型语言支持

    http://www.infoq.com/cn/articles/jdk-dynamically-typed-language Java虚拟机的字节码指令集的数量自从Sun公司的第一款Java虚拟机问 ...

  10. JS数组常用方法

      // 来自 http://www.runoob.com/jsref/jsref-obj-array.html   var arr01 = [ "fuc" , "shi ...