题目链接:
https://vjudge.net/contest/207453#problem/A
题目大意:
有一个农夫,要从(0,0)点出发到(x,y)点的最短距离,其中有n个水滩(Ai , Bi),农夫需要绕过n个水滩到达目的地。
数据范围:
(-500≤x,y ≤ 500)
(-500≤Ai ,Bi ≤ 500)
解题思路:
直观思路:将点放在二维坐标系中,然后从(0,0)点开始进行广度优先搜索,到达(x,y)点时返回最短路。
由于二维数组下标不能为负数,将整个二维坐标系向左平移500个单位再向上平移500个单位,则问题转化为从(500,500)点到(500+x,500+y)点的最短距离。水滩在二维数组中用1表示,可以走的点用0表示。
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e4;
typedef long long LL;
int num[maxn + 5][maxn + 5]={0};
int a,b;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
int vis[maxn+5][maxn+5];
struct point{
int x,y;
int flag;
}s,q;
int bfs(int x,int y){
intxx,yy,flag;
s.x = x,s.y =y,s.flag = 0;
queue<point>que;
vis[x][y] = 1;
que.push(s);
while(!que.empty()){
s =que.front();
que.pop();
if(s.x ==a+500&&s.y == b+500) return s.flag;//到达(500+x,500+y)时直接返回最短距离
for(int i= 0;i<4;i++){
xx =s.x + dx[i];
yy =s.y + dy[i];
flag= s.flag + 1;
if(vis[xx][yy]||xx>1000||yy>1000||xx<0||yy<0||num[xx][yy]==1)//越界和遇见水滩时跳过
continue;
vis[xx][yy]= 1;
q.x =xx,q.y = yy,q.flag = flag;
que.push(q);
}
}
return 0;
}
int main(){
int n;
cin >> a>> b >> n;
while(n--){
int x,y;
cin >>x >> y;
num[x+500][y+500]= 1;//水滩置为1
}
int ans =bfs(500,500);
cout <<ans << endl;
return 0;
}