【SSL2278】Oliver的救援【BFS】

本文介绍了一道关于寻找地图上两点间最短路径的问题,利用BFS(宽度优先搜索)算法解决。在一个N*N的网格中,部分区域不可通行,目标是在可通行区域内从起点到达终点,算法详细展示了如何通过队列实现BFS搜索,找到从起点到终点的最少步数。

Description

在你的帮助下,Oliver终于追到小X了,可有一天,坏人把小X抓走了。这正是Oliver英雄救美的时候。所以,Oliver又找到哆啦A梦,借了一个机器,机器显示出一幅方格地图,它告诉Oliver哪里能走,哪里不能走,。并且Oliver在这个地图的任意地方,而小X在任意地方。时间紧急,Oliver想知道,最少要走多少个格子,才能找到小X。(只能直走,不能斜走)。

Input

共N+2行,第一行为N,以下N行N列0-1矩阵,1表示不能通过,0表示可以通过(左上角和右下角为0). N<=1000.第三行有四个数:qx,qy,zx,zy表示Oliver的起始地点和小X的起始地点。

Output

共一个数,为最少的走的格子数.

Sample Input

10
0100110100
0001110010
1000000001
1000100011
0000101100
1000001100
1001010011
0000010100
0101010000
1001000001
1 7 10 2

Sample Output

14

分析

这道题跟电子老鼠差不多,也是一道模板题。只是输入有点不同 ,这道题要用字符串处理。因为不用输出路径,所以不用记录father,也不用递归输出(但也在代码里附上)。1000的范围只能用BFS,按模板打,搜到走人即可。注意st数组的大小哦!

上代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,sx,sy,ex,ey,st[1000001][3];
int dx[5]={0,0,1,0,-1},s,dy[5]={0,-1,0,1,0},last,fa[101];
int h,t;
char a[1001][1001];//字符串处理
void print(int x){
	if(x==0) return;
	s++;
	print(fa[x]);
	if(x!=last)
		printf("(%d,%d)->",st[x][1],st[x][2]);
	else
		printf("(%d,%d)\n",st[x][1],st[x][2]);
}
void bfs(){
	h=0;t=1;
	st[1][1]=sx;st[1][2]=sy;st[1][3]=0;
	while(h<t){
		h++;
		for(int i=1;i<=4;i++){
			int xx=dx[i]+st[h][1];
			int yy=dy[i]+st[h][2];
			if(xx>0&&xx<=n&&yy>0&&yy<=n&&a[xx][yy]=='0'){
				t++;
				//fa[t]=h;
				st[t][1]=xx;
				st[t][2]=yy;
				st[t][3]=st[h][3]+1;
				a[xx][yy]=1;
				if(st[t][1]==ex&&st[t][2]==ey){
					s=0;
					last=t;
					//print(t);
					cout<<st[t][3];
					t=0;
					return;
				}
			}
		}
	}
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
		}
	}	
	cin>>sx>>sy>>ex>>ey;
	bfs();
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值