AcerMoOi之路

一只蒟蒻

POJ 3083 Children of the Candy Corn

题目大意,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
个人分类: 爆搜
上一篇POJ 3134 Power Calculus IDA*
下一篇NOIP 2014 Day2T2 寻找道路
想对作者说点什么? 我来说一句

pku_acm3083

2010年06月10日 12KB 下载

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

关闭
关闭