poj 3083 Children of the Candy Corn (DFS+BFS)

原创 2015年07月09日 00:58:15

Children of the Candy Corn
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10881   Accepted: 4678

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

Source


题目链接:一个迷宫,S为起点,E为终点。

  三种方法从S到E:1.从前进方向的左侧开始顺时针寻找下一个可行点;

2.从前进方向的右侧开始逆时针寻找下一个可行点;

3.找最短路径;

  求分别通过这三种方法走过的格子数。


解题思路:前两种方法用DFS,四个方向,若是方法一,下一个点不可行时,顺时针判断下一个点,可行时,逆时针回到上一个方向。即nextdex=(dex+1)%4和nextdex=(dex+3)%4,方法二直接两个式子位置互换。找最短路显然用BFS,要注意visit数组的标记!!当时忘了TLE了好久。


代码如下:

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
char a[42][42];
int vis[42][42];
int n,m,cnt;
bool p;
struct node   //每个格子的信息,num是起点到当前格子的步数
{
	int x,y,num;
};
void dfsl(int x,int y,int i)   //左转优先
{
	if(p||a[x][y]=='E')
	{
		p=true;
		return ;
	}
	int cx=x+dx[i];
	int cy=y+dy[i];
	while(cx<0||cx>=n||cy<0||cy>=m||a[cx][cy]=='#')//下一个点不可行
	{
		i=(i+3)%4;                //顺时针转判断下一个点
		cx=x+dx[i];
		cy=y+dy[i];
	}
	cnt++;
	dfsl(cx,cy,(i+1)%4);      //下一个点可行,方向逆时针回到上一个方向
}
void dfsr(int x,int y,int i)  //右转优先,和左转优先正好相反
{
	if(p||a[x][y]=='E')
	{
		p=true;
		return ;
	}
	int cx=x+dx[i];
	int cy=y+dy[i];
	while(cx<0||cx>=n||cy<0||cy>=m||a[cx][cy]=='#')
	{
		i=(i+1)%4;
		cx=x+dx[i];
		cy=y+dy[i];
	}
	cnt++;
	dfsr(cx,cy,(i+3)%4);
}
int bfs(int sx,int sy)  //找最短路径
{
	queue<node>q;
	node sd;
	sd.x=sx;
	sd.y=sy;
	sd.num=1;
	q.push(sd);
	vis[sx][sy]=1;       //起点也要标记
	while(!q.empty())
	{
		node no=q.front();
		q.pop();
		for(int i=0;i<4;i++)//每个方向都要判断
		{
			int cx=no.x+dx[i];
			int cy=no.y+dy[i];
			if(vis[cx][cy]||cx<0||cx>=n||cy<0||cy>=m||a[cx][cy]=='#')
				continue;       //下一个点不可行,换一个方向
			sd.x=cx;            //下一个点可行,步数加以后加入队列
			sd.y=cy;
			sd.num=no.num+1;
			vis[cx][cy]=1;
			if(a[cx][cy]=='E')
				return sd.num;
			q.push(sd);
		}
	}
}
int main()
{
	int t,sx,sy;
	scanf("%d",&t);
	while(t--)
	{
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&m,&n);
		for(int i=0;i<n;i++)
		{
			scanf("%s",&a[i]);
			for(int j=0;j<m;j++)
			{
				if(a[i][j]=='S')
				{
					sx=i;
					sy=j;
				}
			}
		}
		cnt=1,p=false;
		dfsl(sx,sy,0);
		printf("%d ",cnt);
		cnt=1,p=false;
		dfsr(sx,sy,0);
		printf("%d ",cnt);
		printf("%d\n",bfs(sx,sy));
	}
	return 0;
}



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

相关文章推荐

POJ 3083 Children of the Candy Corn (DFS+BFS) -- 解题报告

题目链接题目大意给定一个二维迷宫, “#” 表示不可走的位置,“.” 表示可走的位置,起点为 “S”,终点为 “E”。问左手扶墙走、右手扶墙走和最短路线的步数各是多少。解题思路本题需要输入三种走迷宫的...

poj 3083 Children of the Candy Corn dfs+bfs

Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and mu...

POJ 3083 Children of the Candy Corn (BFS ,DFS) -- from lanshui_Yang

Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and ...

POJ 3083 Children of the Candy Corn (DFS + BFS)

Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10145 ...

[Poj 3083] Children of the Candy Corn bfs+dfs

Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12060 ...

poj 3083 Children of the Candy Corn(dfs+bfs)

http://poj.org/problem?id=3083 题意:有一个W*H的map,‘#’表示障碍,'.'表示空地,'S'表示起点,'E'表示终点,且保证起点与终点各有一个。 分别输出左转优...

POJ 3083:Children of the Candy Corn(DFS+BFS)

Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Su...

poj-3083-Children of the Candy Corn-DFS+BFS

一个感觉超级恶心的搜索题。—–==—– 题目大意: 给一个图,从S走到E,求三组解,第一组是一直靠着左边走需要的步数,第二组是一直靠着右边走需要的步数,第三组是最短路径,对于第三组,比较简单直...

POJ 3083 Children of the Candy Corn dfs+bfs

题意:给出一个迷宫,不超过40*40。分别求出从起点一直沿左走,一直沿右走,直到终点所需要的步数。以及所需要的最小步数。 题解:用bfs求出最小步数,dfs求一直向左或者向右走得步数。 #in...
  • Tsaid
  • Tsaid
  • 2011-09-08 22:21
  • 946

[POJ 3083]Children of the Candy Corn[DFS+BFS]

题目链接:[POJ 3083]Children of the Candy Corn[DFS+BFS] 题意分析: 从起点S到终点E,贴着左边的墙壁走需要几步?贴着右边的墙壁走需要走几步?直接走最短路需...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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