【BFS】最小转弯问题

Description

给出一张地图,这张地图被分为 n×m(n,m<=100)个方块,任何一个方块不是平地就是高山。平地可以通过,高山则不能。现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能到达目的地(x2,y2)?你只能沿着水平和垂直方向的平地上行进,拐弯次数就等于行进方向的改变(从水平到垂直或从垂直到水平)的次数。例如:如图 1,最少的拐弯次数为5。

Input

第 1行:n m 第 2至n+1行:整个地图地形描述(0:空地;1:高山), 如图,第2行地形描述为:1 0 0 0 0 1 0 第3行地形描述为:0 0 1 0 1 0 0 …… 第n+2行:x1 y1 x2 y2 (分别为起点、终点坐标)

Output

s (即最少的拐弯次数

Sample Input

5 7
1 0 0 0 0 1 0
0 0 1 0 1 0 0
0 0 0 0 1 0 1
0 1 1 0 0 0 0
0 0 0 0 1 1 0
1 3 1 7

Sample Output

5


解题思路

广搜
只比板子多了记录转弯
可以把方向数组的“上下左右”巧妙地改变一下顺序,按水平顺序“上左下右”,i%2==0是一个水平情况,i%2!=0是一个水平情况,发现扩展的点和当前点不是一个情况,转弯次数加1


#include<iostream>
#include<cstdio>
using namespace std;
const int way[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//上,左,下,右
int a[150][150],n,m,s[150][150][2],sx,sy,ex,ey;
int v[100100][2],h,t=1;
bool check(int x,int y){
	return (x>0&&x<=n&&y>0&&y<=m);
}
void BFS(int x,int y){
	s[x][y][0]=1;//s[][][0]记录转弯次数
	s[x][y][1]=-1;//s[][][1]记录水平情况,第一个点特殊标记
	a[x][y]=1;
	v[t][0]=x,v[t][1]=y;
	while(h++<t){
		x=v[h][0],y=v[h][1];
		for(int i=0;i<4;i++){
			int xx=x+way[i][0];
			int yy=y+way[i][1];
			if(check(xx,yy)&&!s[xx][yy][0]&&!a[xx][yy]){
				v[++t][0]=xx,v[t][1]=yy;
		     	if(s[x][y][1]==-1)s[xx][yy][0]=s[x][y][0];//特判是不是第一个点过来的
				   else
			    	if(i%2!=s[x][y][1])s[xx][yy][0]=s[x][y][0]+1;//如果不是一个水平情况,转弯数+1
				       else s[xx][yy][0]=s[x][y][0];
				s[xx][yy][1]=i%2;
				a[xx][yy]=1;
				if(xx==ex&&yy==ey)return;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++)
	        scanf("%d",&a[i][j]);
	scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
	BFS(sx,sy);
	printf("%d",s[ex][ey][0]-1);
} 
发布了45 篇原创文章 · 获赞 0 · 访问量 371

猜你喜欢

转载自blog.csdn.net/qq_39940018/article/details/103432469