POJ 3083 Children of the Candy Corn

版权声明:我这么弱的蒟蒻,虽然博文不是很好,但也请标明转发地址喵! https://blog.csdn.net/ACerAndAKer/article/details/79953487

题目大意,t组数据循环读入,注意,题目输入的是m列n行,emmm,被坑了,有一个起点S,一个终点E,对于每组数据你需要输出,优先向左转到达E的步数,优先向右转到达E的步数,以及最少到达E的步数

优先向左转,我们定义,从某步从x->y,那么从x到y的方向即为当前正方向,优先向左转的意义为优先到当前正方向的左方,左方没有道路,那么就按正常搜素

优先向右转同左

思路,两个dfs+一个bfs,dfs求带优先级的,bfs求最短路

题目貌似保证S只存在于四条边界,所以我们需要判断挨着哪条边,然后以墙的另一边为正方向

###     | #S#    |
S..     | E..    |   同理
#E#     | #.#    |
->正方向  向下正

然后我们通过一步bulabula的操作,来滚动下标,确保每次优先走的方向为左 ,向右同理

代码

By Acer.Mo
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int t,h,l,sx,sy,ex,ey;//记录起终点位置
char map[200][200];
int dx1[4][2]={{0,-1},{-1,0},{0,1},{1,0}};//优先向左
int dx2[4][2]={{0,1},{-1,0},{0,-1},{1,0}};//优先向右
struct edge 
{
	int x,y;
	int cost;
	bool friend operator < (edge a,edge b)
	{
		return a.cost>b.cost;
	}
};//跑bfs最短路
int dfs1(int x,int y,int fx,int step)//优先向左
{
	if (x==ex&&y==ey) return step;//到达终点,return步数
	for (int i=0;i<4;i++)
	{
		int k=((fx+3)%4+i)%4;//确保优先向左,最后向后
		int xx=x+dx1[k][0];
		int yy=y+dx1[k][1];
		if (xx<0||yy<0||xx>=h||yy>=l||map[xx][yy]=='#') continue//不合法;
		return dfs1(xx,yy,k,step+1);//传递
	}
}
int dfs2(int x,int y,int fx,int step)//优先向右
{
	if (x==ex&&y==ey) return step;
	for (int i=0;i<4;i++)
	{
		int k=((fx+3)%4+i)%4;//确保优先向右
		int xx=x+dx2[k][0];
		int yy=y+dx2[k][1];
		if (xx<0||yy<0||xx>=h||yy>=l||map[xx][yy]=='#') continue;
		return dfs2(xx,yy,k,step+1);
	}
}
int bfs()//最普通的bfs
{
	int vis[200][200];memset(vis,0,sizeof(vis));
	int ff[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
	priority_queue<edge>q;//优先队列优化
	edge now;
	now.x=sx;now.cost=0;now.y=sy;
	q.push(now);
	vis[sx][sy]=1;
	while (q.size())
	{
		now=q.top();q.pop();
		if (now.x==ex&&now.y==ey) return now.cost+1;
		for (int i=0;i<4;i++)
		{
			edge t;
			int xx=now.x+ff[i][0];
			int yy=now.y+ff[i][1];
			if (vis[xx][yy]||xx<0||yy<0||xx>h||yy>l) continue;
			if (map[xx][yy]=='S'||map[xx][yy]=='E'||map[xx][yy]=='.')
			{
				t.cost=now.cost+1;t.x=xx;t.y=yy;
			        q.push(t);vis[xx][yy]=1;
			}
		}	
	}	
}
int main()
{
	cin>>t;
	while (t--)
	{
		cin>>l>>h;
		for (int i=0;i<h;i++)
		{
			scanf("%s",map[i]);
		}
		for (int i=0;i<h;i++)
		{
			for (int k=0;k<l;k++)
			{
				if (map[i][k]=='S') sx=i,sy=k;
				if (map[i][k]=='E') ex=i,ey=k;
			}
		}
		int fuck,flag;
		if (sx==0) fuck=3,flag=3;//判断初始方向
		else if (sx==h-1) fuck=1,flag=1;
		else if (sy==0) fuck=2,flag=0;
		else if (sy==l-1) fuck=0,flag=2;
		printf("%d ",dfs1(sx,sy,fuck,1));
		printf("%d ",dfs2(sx,sy,flag,1));
		printf("%d\n",bfs());
	}
	return 0;
} 

阅读更多

Children of the Candy Corn

02-06

DescriptionnnThe 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. nnOne 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.)nnAs 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.nInputnnInput 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'.nnExactly 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 ('#').nnYou may assume that the maze exit is always reachable from the start point.nOutputnnFor 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.nSample Inputnn2n8 8n########n#......#n#.####.#n#.####.#n#.####.#n#.####.#n#...#..#n#S#E####n9 5n#########n#.#.#.#.#nS.......En#.#.#.#.#n#########nSample Outputnn37 5 5n17 17 9

没有更多推荐了,返回首页