欢乐赛G

POJ1376
原题链接https://vjudge.net/contest/350953#problem/G
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一道bfs的题,计算从所给的起点到终点的时间,需要注意的是机器人的头的方向还要特别考虑 ,只能朝面朝的方向走,而且只能向左转90或者向右转90(也就是说每个情况可以延伸出三种情况,向前,向左转,向右转)同时转身也会消耗一次时间,机器人前进的步数有三种,向前1 2 3 步也就是三种情况
将情况理清之后便是建图,这题意有点难懂还是英文,而且有点小神奇(biantai?)
题目给出了9×10 的图但是这个图是真正的地图上的障碍物的分布形况,1个点代表真正地图四个点(4个点会有重叠部分,主要针对有障碍物(1*1的正方形会占4个点)的格子进行判断),唔,也就是说正式地图比给出的地图要横竖多一行,也就是10×11;
在这里插入图片描述
题目给的图就是样例的图,可以数一下格数,注意机器人走的是轨道,不是格子中间,而障碍物会将周围4个路(四条边)全部挡住,所以读取地图障碍物要注意,同时这是在一个商店里,(读题可以发现他提出了对于墙壁旁边的轨道的距离)也就是说,墙壁是不能走(比如(0,0)(0,1))的,也就是边界,只能沿着中间轨道走。(wa了14发的惨痛教训)
题意就是这样,细节有点多,又是英文题,所以本来其实算是基础的bfs题就显得有些困难。

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
long long n, m;
long long map[100][100];//地图
long long vis[100][100][10];//多开数组记录来到这个点位的方向,不同方向到达这个点位也是不同的情况
long long mv[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};//移动的方向
struct node
{
	long long x;//x轴
	long long y;//y轴
	long long t;//时间
	long long z;//方向
} s, e;//s为记录起始状态,e记录结束状态
long long bfs()
{
	queue<node> q;//建立队列记录数据
	q.push(s);//放入起始数据
	memset(vis, 0, sizeof(vis));
	node s1, e1;//s1为当前数据变化前的数据,e1为经过变化之后的数据
	long long i, j;
	while (!q.empty())
	{
		s1 = q.front();
		q.pop();
		//printf("s=%lld %lld %lld %lld\n",s1.x,s1.y,s1.t,s1.z);
		//if(s1.x==4&&s1.y==7&&s1.z==0)
		//	{
		//		printf("%lld",vis[e1.x][e1.y][e1.z]);
		//		printf("*******************\n");
		//	}
		if (s1.x == e.x && s1.y == e.y)//结束条件,到达终点
		{
			return s1.t;
		}
		e1.x = s1.x;
		e1.y = s1.y;
		e1.t = s1.t + 1;//旋转一次时间要增加1,同时我们此时不进行这个方向的判断,要放入队列,以保证时间不会乱,
		e1.z = (s1.z + 1) % 4;//+1根据之前设定的方向为向右旋转
		//	if(s1.x==4&&s1.y==7)
		//	{
		//		printf("%lld\n",vis[e1.x][e1.y][e1.z]);
		//		printf("%lld %lld %lld\n",e1.x,e1.y,e1.z);
		//		printf("*******************\n");
		//	}
		if (vis[e1.x][e1.y][e1.z] == 0)//判断这个状态是否出现过
		{
			vis[e1.x][e1.y][e1.z] = 1;//标记
			q.push(e1);
		}
		e1.x = s1.x;
		e1.y = s1.y;
		e1.t = s1.t + 1;//同上
		e1.z = (s1.z-1+4) % 4;//想左旋转,+4以保证不会出现负数
		//	if(s1.x==4&&s1.y==7)
		//	{
		//		printf("%lld\n",vis[e1.x][e1.y][e1.z]);
		//		printf("%lld %lld %lld\n",e1.x,e1.y,e1.z);
		//		printf("*******************\n");
		//	}
		if (vis[e1.x][e1.y][e1.z] == 0)
		{
			vis[e1.x][e1.y][e1.z] = 1;//标记
			q.push(e1);
		}
		for (j = 1; j <= 3; j++)//判断不进行旋转向前进的情况,三种情况
		{
			e1.z = s1.z;
			e1.t = s1.t;
			e1.x = s1.x + mv[e1.z][0] * j;
			e1.y = s1.y + mv[e1.z][1] * j;
			//	printf("%lld %lld****\n",mv[i][0]*j,mv[i][1]*j);
			if (map[e1.x][e1.y] == 1)//如果走到障碍物就要跳出,因为只能沿轨道走,如果现在比如果1的位置出现障碍物,就不可能跳过障碍物去走两步或者三步,会不障碍物挡住而不能前进,所以后面的步数的情况也不需要考虑,直接跳出
			{
				break;
			}
			if (e1.x <= 0 || e1.y <= 0 || e1.x >= n || e1.y >= m || vis[e1.x][e1.y][e1.z] == 1)//出届或者情况出现过跳出,注意边界位置!!!!
			{
				continue;
			}
			e1.t++;//时间+1,标记放入队列
			vis[e1.x][e1.y][e1.z] = 1;
			q.push(e1);
		}
	}
	return -1;//如果队列中所有情况跑完还没有到达终点,说明不能达到,输出-1;
}
int main()
{
	long long i, j;
	while (~scanf("%lld %lld", &n, &m))
	{
		if (n == 0 && m == 0)//如果数据为0 0 跳出
		{
			break;
		}
		long long t;
		memset(map, 0, sizeof(map));
		for (i = 0; i < n; i++)
		{
			for (j = 0; j < m; j++)
			{
				scanf("%lld", &t);//读取障碍物的状态,注意是障碍物,并不是直接是地图
				if (t == 1)//将障碍物读入地图,至于为什么是这四个点,请将样例数据跟地图数据进行比较来确定。
				{
					map[i][j] = 1;
					map[i + 1][j] = 1;
					map[i][j + 1] = 1;
					map[i + 1][j + 1] = 1;
				}
			}
		}
		scanf("%lld %lld %lld %lld", &s.x, &s.y, &e.x, &e.y);//读取起始位置和终止位置
		//	cout<<endl;
		//	map[s.x][s.y]=3;
		//	map[e.x][e.y]=3;
		//	for(i=0; i<n; i++)
		//	{
		//		for(j=0; j<m; j++)
		//		{
		//			printf("%lld ",map[i][j]);
		//		}
		//		cout<<endl;
		//	}
		char ss[15];//读取方向,由于是英文用字符串读取
		s.t = 0;
		scanf("%s", ss);//四个方向的首字母不同,直接判断首字母就行
		if (ss[0] == 'e')//对于每个方向的数字的代表要跟mv数组的方向对应,也就是说mv[s.z][0]以及mv[s.z][1]要刚好是朝这个方向移动。
		{
			s.z = 0;
		}
		else if (ss[0] == 's')
		{
			s.z = 1;
		}
		else if (ss[0] == 'w')
		{
			s.z = 2;
		}
		else if (ss[0] == 'n')
		{
			s.z = 3;
		}
		long long sum = bfs();//开始bfs
		printf("%lld\n", sum);
	}
	return 0;
}

发布了130 篇原创文章 · 获赞 3 · 访问量 1599

猜你喜欢

转载自blog.csdn.net/yeyuluo/article/details/103963403