暑期集训的一天下了大雨,地面出现了许多泥坑,一踩一脚泥。小tao从坐标平面上的点(0,0)出发,准备去向文瀛餐厅(X , Y)(-500≤ X , Y≤ 500)。在路上有N(1≤ N≤ 10000)个泥坑,位于点(Ai,Bi)(-500≤ Ai , Bi≤500)。
小tao为了好好集训,买了一双新鞋子来鼓舞自己,他不想弄脏鞋子,但他也想尽快到达餐厅干饭。如果小tao只能平行于轴线移动,并在整数坐标点转向,请问他到达餐厅且保持鞋子干净要走的最小距离是多少?
保证总是有一条没有泥的路使得小tao可以走到餐厅。
输入描述
第1行:三个空间分隔的整数:X、Y和N。 表示餐厅坐标以及泥坑的数量。
第2..N+1行:第i+1行包含两个空格分隔的整数:Ai和Bi。 表示每个泥坑的坐标。
输出描述
输出小tao在不踩泥的情况下到达文瀛餐厅所需的最小距离。
样例输入
1 2 7 0 2 4 2 3 1 1 1 2 2 -1 1 -1 3
样例输出
11
题解:
使用bfs:
判断正在搜索的点的上下左右四个方向的点是否符合要求,即 在图的范围中,且不是泥地,且没有被搜索过(让每个点的距离为第一次搜索到的距离,即可使其对应的距离最小),如果符合要求,即这个点的距离为正在搜索的点的距离加1,再将这个点放入队列中。
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int a,b,n;
int g[N][N];
typedef pair<int,int> PII;
int d[N][N];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//上下左右四个方向
int bfs()
{
queue<PII> q;//队列,宽度优先搜索,使得距离原点距离为1,2,3,4。。。的点依次搜索
memset(d,-1,sizeof d);
d[500][500]=0;
q.push({500,500});
while(q.size())
{
PII t=q.front();//找出队列头节点,即为此次要搜索的点
q.pop();//将此点从队列中移除
// for(int i=0;i<4;i++)/四个方向依次尝试
{
int x=t.first+dx[i],y=t.second+dy[i];
if(x>=0&&x<=1000&&y>=0&&y<=1000&&g[x][y]==0&&d[x][y]==-1)//此点不超出图的范围,且不是泥点,且没被搜索过,即此点的距离为搜索点+1
{
d[x][y]=d[t.first][t.second]+1;
q.push({x,y});//将符合要求的点放入队列中
}
}
}
return d[500+a][500+b];
}
int main()
{
cin>>a>>b>>n;
while(n--)
{
int a1,b1;
cin>>a1>>b1;
g[a1+500][b1+500]=1;
}
cout<<bfs()<<endl;
return 0;
}