离开中山路~广搜的简单空间优化

题目描述

在这里插入图片描述

输入样例

3
001
101
100
1 1 3 3

输出样例

4

AC Code

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int maxn = 1005;
bool m[maxn][maxn];
struct xy{
	int x,y,s;
}xy1;
queue<xy> q;
int x1,x2,y1,y2,n;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
void bfs(){
	xy1.x = x1,xy1.y = y1,xy1.s = 0;
	q.push(xy1);
	m[x1][y1] = 1;
	while(!q.empty()){
		xy t = q.front();q.pop();
		if(t.x == x2 && t.y == y2){
			cout<<t.s;
			return ;
		}
		for(int i=0;i<4;i++){
			int nx = t.x + dx[i],ny = t.y + dy[i];
			if((nx>=1&&nx<=n)&&(ny>=1&&ny<=n)&&!m[nx][ny]){
				xy t1;
				t1.x = nx,t1.y = ny,t1.s = t.s+1;
				q.push(t1);
				m[nx][ny] = 1;
			}
		}
	}	
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		string st;cin>>st;
		for(int j=1;j<=n;j++){
			m[i][j] = st[j-1]-'0';
		}
	}
	cin>>x1>>y1>>x2>>y2;
	bfs();
	return 0;
}

解释

〇拿到这道题,计算最短距离,很容易想到需要使用广搜,写完广搜提交代码之后,直接爆了9个MLE,说明空间爆了,需要优化,看了评论区大犇的做法之后,有所感触,写以记之。
①数据结构:bool m[maxn][maxn];使用m布尔数组,同时存储整张图并判断某个点是否已经路过。输入这张图:

for(int i=1;i<=n;i++){
	string st;cin>>st;
	for(int j=1;j<=n;j++){
		m[i][j] = st[j-1]-'0';
	}
}

👆用string变量输入这张图,因为输入是字符串。
判断是否经过,于bfs中:m[nx][ny] = 1;m[x1][y1] = 1;即如果经过了,这个点设置为1(true),没经过,则为0(false)<体现在图中,如果经过了,这个点就成为了障碍,每经过,则是0,以后可以经过>。
②结构体:需要先建立结构体,因为此处的广搜不是遍历图的广搜,一个个输出结点即可。此处的广搜是输出最短路径,因此路径上的每个点都应予以存储于队列中:

struct xy{
	int x,y,s;
}xy1;

队列:使用#include <queue>引用STL队列头文件,再使用queue<xy> q;建立xy型队列变量q。
广搜:

int dx[] = {0,0,1,-1};//方向数组
int dy[] = {1,-1,0,0};//方向数组
void bfs(){
	xy1.x = x1,xy1.y = y1,xy1.s = 0;//第一个结点,优先入列
	q.push(xy1);
	m[x1][y1] = 1;
	while(!q.empty()){
		xy t = q.front();q.pop();
		if(t.x == x2 && t.y == y2){
			cout<<t.s;
			return ;
		}
		for(int i=0;i<4;i++){
			int nx = t.x + dx[i],ny = t.y + dy[i];
			if((nx>=1&&nx<=n)&&(ny>=1&&ny<=n)&&!m[nx][ny]){
				xy t1;
				t1.x = nx,t1.y = ny,t1.s = t.s+1;
				q.push(t1);
				m[nx][ny] = 1;
			}
		}
	}	
}

👆没什么好说的,很清晰的思路。
③AC。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值