【题目描述】
山山来到了 CCF 城堡,这个城堡是一个 n*m 的迷宫。入口是城堡的左上角(1, 1),出
口是城堡的右下角(n, m)。 CCF 为了防止被太多的人膜拜,在城堡的某些小格中布置了陷阱,
有些没有。
这些陷阱是 CCF 专用的神奇的磁力装置。只要你所在的点与任何一个陷阱的曼哈顿距
离小于 k,就会被吸回起点(1, 1)。显然,当 k 值过大的时候,我们是永远不可能到达出口
(n, m)的。所以为了去膜拜 CCF,我们需要知道 k 最大能是多少。
【输入文件】
第一行三个正整数 n,m,c,表示迷宫的大小和陷阱的数量。
接下来 c 行,每行两个数,表示每个陷阱的坐标。数据保证陷阱坐标不超出迷宫。
【输出文件】
一个整数,能通关的最大 k 值。如果不能通关,输出 0。
【输入样例 1】
5 5 1
3 3
【输出样例 1】
2
【输入样例 2】
2 2 2
1 2
2 1
【输出样例 2】
0
【数据规模】
对于 60%的数据,
对于 100%的数据,
【hints】
(x1,y1) 和(x2,y2)的曼哈顿距离定义为|x1 - x2| + |y1 - y2|。
这题我们测的时候的数据比较水,各种二分都过了,我一开始也是用的二分,但是我写错了。
但是二分肯定不是正解,我最后用的是沈队教我的bfs过的。
首先我们看到这么多陷阱,想想怎么处理,我们可以先广搜一边,遍历一遍图,把每个点离最近的陷阱的曼哈顿距离算出来。
然后我们就会发现,从起点到终点的路径中只有离陷阱最近的距离有影响,
所以我们用ans记录从起点到该点的路径上距离陷阱最近的距离的最大值,
然后我们在bfs扫一遍,就可以输出答案了。
还要注意用循环队列防止运行错误。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define il inline
#define db double
using namespace std;
il int gi()
{
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
y=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*y;
}
int n,m,c;
int dist[5]={0,1,0,-1,0};
int k[1000045][2];
int headd,taill;
int a,b,x,y;
bool vis[1045][1045];
int dis[1045][1045];
il void bfs1()
{
while(headd!=taill)
{
a=k[headd][0],b=k[headd++][1];
headd%=1000000;
for(int i=0;i<4;i++)
{
x=a+dist[i],y=b+dist[i+1];
if(x<1||y<1||x>n||y>m||vis[x][y])
continue;
vis[x][y]=1;
dis[x][y]=dis[a][b]+1;
k[taill][0]=x;
k[taill++][1]=y;
taill%=1000000;
}
}
}
int t[1000045][2];
int head,tail=1;
int ans[1045][1045];
il void bfs2()
{
memset(vis,0,sizeof(vis));
t[0][0]=1;
t[0][1]=1;
ans[1][1]=dis[1][1];
while(head!=tail)
{
a=t[head][0],b=t[head++][1];
head%=1000000;
for(int i=0;i<4;i++)
{
x=a+dist[i],y=b+dist[i+1];
if(x<1||y<1||x>n||y>m||ans[x][y]>=min(ans[a][b],dis[x][y]))
continue;
ans[x][y]=min(ans[a][b],dis[x][y]);
t[tail][0]=x;
t[tail++][1]=y;
tail%=1000000;
}
}
}
int main()
{
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
memset(ans,-1,sizeof(ans));
n=gi(),m=gi(),c=gi();
for(int i=1;i<=c;i++)
{
x=gi(),y=gi();
vis[x][y]=1;
k[taill][0]=x;
k[taill++][1]=y;
}
bfs1();
bfs2();
printf("%d\n",ans[n][m]);
return 0;
}