P7663
思路还是比较简单的,完全没有蓝题的难度。
考虑bfs,每遇到一个点就往外广度搜索,去找最近的点。
时间看起来比较多,但到了后面有很多树,每个点的时间是非常快的,再加点优化,时间其实差不多是O(g)的。
具体请见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node
{
int x,y;
}now,nex;
const int dir[4][2] = {0,-1,-1,0,0,1,1,0};
char a[505][505];
int r,s,g;
bool vis[505][505];
int f(int x1,int y1,int x2,int y2)//算距离
{
return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
}
int bfs(int x,int y)//bfs模板不用多讲吧
{
memset(vis,0,sizeof vis);
queue<node> que;
int ans = 0x7ffffff;
now.x = x;now.y = y;
que.push(now);
while(!que.empty())
{
now = que.front();
que.pop();
if(f(now.x,now.y,x,y)>ans)continue;//比最小值大就没必要枚举下去了(优化)
for(int i = 0;i < 4;i++)
{
int xx = now.x+dir[i][0];
int yy = now.y+dir[i][1];
if(xx<1||xx>r||yy<1||yy>s||vis[xx][yy])continue;
vis[xx][yy] = 1;
int s = f(xx,yy,x,y);
if(s >= ans)continue;//同上
if(a[xx][yy] == 'x')ans = s;//注意只有是当前位置有苹果树才更新答案
nex.x = xx;nex.y = yy;
que.push(nex);
}
}
return ans;
}
int main()
{
// freopen("jabuke.in","r",stdin);
// freopen("jabuke.out","w",stdout);
cin >> r >> s;
for(int i = 1;i <= r;i++)
for(int j = 1;j <= s;j++)
cin >> a[i][j];
cin >> g;
while(g--)
{
int x,y;
cin >> x >> y;
if(a[x][y] == 'x')//如果这个点是x就直接输出0(优化)
{
cout << "0\n";
continue;
}
cout << bfs(x,y) << endl;
a[x][y] = 'x';//一定要记得
}
return 0;
}