POJ 3083 Children of the Candy Corn

原创 2018年04月15日 21:43:04

题目大意,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;
} 

版权声明: https://blog.csdn.net/ACerAndAKer/article/details/79953487

彻底掌握 Javascript(十九)Iterator 迭代器【专家辅导】

ES6 引入了 Iterator 迭代器,这是很重要的特性,所有相关javascript的类,都实现了这个接口,从而可以利用 for-of 来循环,具体的看课程吧,很有用的特性。
  • 2017年06月30日 20:59

POJ 3083 C - Children of the Candy Corn

#include #include #include #include using namespace std; int sx, sy, ex, ey, d1,d2, n, m, next[4...
  • Autii
  • Autii
  • 2016-08-02 10:36:51
  • 273

pku_acm3083

  • 2010年06月10日 15:27
  • 12KB
  • 下载

【poj 3083】Children of the Candy Corn 中文题意&题解&代码(C++)

poj3083
  • DERITt
  • DERITt
  • 2016-03-21 16:48:58
  • 470

【POJ 3083】Children of the Candy Corn

POJ【3083】Children of the Candy Corn Dfs+Bfs
  • ChallengerRumble
  • ChallengerRumble
  • 2015-06-15 01:45:51
  • 709

POJ 3083 Children of the Candy Corn

Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissio...
  • u014445884
  • u014445884
  • 2014-08-10 13:48:58
  • 219

poj 3083 Children of the Candy Corn

这一题输出说大概的意识就是让你输出从左边开始走到终点,从右边走到终点,和从起点到终点的最短路,三种不同的走法分开写就行了,走的时候控制一下方向就行了,不过这一题有个坑点就是交题的时候要交C++才能过,...
  • qq_35806592
  • qq_35806592
  • 2016-11-04 21:49:45
  • 59

POJ 3083:Children of the Candy Corn

Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissio...
  • u010885899
  • u010885899
  • 2015-07-30 09:13:47
  • 301

POJ 3083 *** Children of the Candy Corn

题意:走迷宫,求一直靠墙向左走和靠墙向右走以及最短路径的长度。 想法:我真是智商感人,写个dfs和bfs都错误多多。一直也没理解到靠墙向左走和靠墙向右走是怎么回事,原来靠墙左走是顺时针走,靠...
  • treeshy
  • treeshy
  • 2015-11-24 09:18:42
  • 115

poj 3083 children of the candy corn

题目大意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 先输出左转优先时,从S到E的步数 再输出右转优先时,从S到E的步数 最后输出S到E的最短步数 W为宽,列数 H...
  • u014227910
  • u014227910
  • 2014-11-02 10:51:05
  • 195
收藏助手
不良信息举报
您举报文章:POJ 3083 Children of the Candy Corn
举报原因:
原因补充:

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