BFS+优先队列 P1126题解 机器人搬重物

代码自己写了一遍,有几个bug调不出,于是参考了这位大佬的题解:​​​​​​题解 P1126 【机器人搬重物】 - 林则徐 的博客 - 洛谷博客

然后顺利AC了。呜呜呜~先看题目吧!

思路很简单,就是BFS。

需要注意的几个点:

  1. 判重:这里我原本只考虑了x,y坐标,但是这样可能会漏解!这边采取的是线性方法。可以使不同的x y direct生成不同的hashr。int hashr(int x,int y,int direct){return direct*2700+x*50+y;}
  2. 碰撞检测:机器人走路每走一步都有可能碰到黑块,因此当他在同一方向上走一步遇到阻碍时,就不必走第二第三步了。
  3. 要求机器人完成任务所需的最少时间,我用了优先队列,将时间最短的点放在队首。
  4. 还有就是方向和转向的数学关系,这点可以大大缩减代码量,减少判断。
    1. case 'N':start.direct=0;break;
      case 'E':start.direct=1;break;
      case 'S':start.direct=2;break;
      case 'W':start.direct=3;break;
    2. int xd[4]={-1,0,1,0};
      int yd[4]={0,1,0,-1};//分别是NESW,与1对应
    3. tmp=(cur.direct+4+1)%4;//右转 tmp=(cur.direct+4-1)%4;//左转

以上是我当时遇到的bug(优先队列可以不用,用不用都能ac)

#include<bits/stdc++.h>
using namespace std;
#define MAX 55
int n,m;
int g[MAX][MAX];
bool vis[50000]={0};
struct robot{
	int x,y,t,direct;
	//direct=0(north)1(east)2(south)3(west) 
	bool operator < (const robot r)const
	{
		return r.t<t; 
	}
}start,endr;
priority_queue <robot> q;
int xd[4]={-1,0,1,0};
int yd[4]={0,1,0,-1};
int hashr(int x,int y,int direct){return direct*2700+x*50+y;}
//优先队列,每次队首是时间最短的 
int bfs()
{
	while(!q.empty())
	{
		robot cur=q.top();
		//cout<<"出队节点:x="<<cur.x<<"y="<<cur.y<<"时间:"<<cur.t<<"方向:"<<cur.direct<<endl; 
		q.pop();
		if(cur.x==endr.x&&cur.y==endr.y)
		{
			return cur.t;
			break; 
		}
		int ha=hashr(cur.x,cur.y,cur.direct); 
		if(vis[ha])continue;
		vis[ha]=1;
		int tmp=(cur.direct+4-1)%4;//左转 
		q.push(robot{cur.x,cur.y,cur.t+1,tmp});
	//	cout<<"入队节点:x="<<cur.x<<"y="<<cur.y<<"时间:"<<cur.t+1<<"方向:"<<tmp<<endl; 
		tmp=(cur.direct+4+1)%4;//右转 
		q.push(robot{cur.x,cur.y,cur.t+1,tmp});
	//	cout<<"入队节点:x="<<cur.x<<"y="<<cur.y<<"时间:"<<cur.t+1<<"方向:"<<tmp<<endl; 
		//cout<<q.size();
		int i=cur.direct;
		for(int j=1;j<=3;j++)
		{			
				int xn=cur.x+j*xd[i];
				int yn=cur.y+j*yd[i];
				//判断是否在边界,是否碰到黑点 
				if(0<xn&&xn<n&&0<yn&&yn<m&&!g[xn-1][yn-1]&&!g[xn-1][yn]&&!g[xn][yn-1]&&!g[xn][yn])
				{
					//将点存入队列 
					q.push(robot{xn,yn,cur.t+1,i});
					//cout<<"入队节点:x="<<xn<<"yn="<<yn<<"时间:"<<cur.t+1<<"方向:"<<cur.direct<<endl; 
				}
				else break;
		}
		//cout<<q.size();
	}
	return -1;
	
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			cin>>g[i][j];
		}
	}
	char c;
	cin>>start.x>>start.y>>endr.x>>endr.y>>c;
	switch(c)
	{
		case 'N':start.direct=0;break;
		case 'E':start.direct=1;break;
		case 'S':start.direct=2;break;
		case 'W':start.direct=3;break;
	}
	start.t=0;
	q.push(start);
	cout<<bfs();
 } 

猜你喜欢

转载自blog.csdn.net/LarsGyonX/article/details/124639919