题意:在5000*5000的平面坐标系内给你警卫与事件发生的坐标,让你求出每个事件距离警卫的最小距离。注意警卫可以朝8个方向移动。
思路:暴力什么的很容易超时,可以用BFS预先将所有警卫到达所有点的最小距离求出,预处理一下就不会超时了,学到了BFS预处理。
坑点:无
#include <bits/stdc++.h>
using namespace std;
const int maxn=300005;
struct Node
{
int x,y,step;
Node()
{
step=0;
}
Node(int a,int b,int c)
{
x=a;
y=b;
step=c;
}
} node[maxn];
int vis[5005][5005],dist[5005][5005];
int dir[][2]= {{1,0},{1,1},{1,-1},{0,1},{0,-1},{-1,1},{-1,0},{-1,-1}};
int n,q;
bool judge(int a,int b)
{
if(a<0||a>5000||b<0||b>5000||vis[a][b])
{
return false;
}
return true;
}
void bfs()
{
queue <Node> q;
for(int i=0; i<n; i++)
{
q.push(node[i]);
dist[node[i].x][node[i].y]=0;
vis[node[i].x][node[i].y]=1;
}
while(!q.empty())
{
Node u=q.front();
q.pop();
for(int i=0; i<8; i++)
{
int x=u.x+dir[i][0],y=u.y+dir[i][1];
if(judge(x,y))
{
q.push(Node(x,y,u.step+1));
dist[x][y]=u.step+1;
vis[x][y]=1;
}
}
}
}
int main ()
{
scanf("%d%d",&n,&q);
for(int i=0; i<n; i++)
{
scanf("%d%d",&node[i].x,&node[i].y);
}
bfs();
int a,b;
for(int i=0; i<q; i++)
{
scanf("%d%d",&a,&b);
printf("%d\n",dist[a][b]);
}
return 0;
}