迷宫 广搜
【题目描述】
山山来到了 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; }
PEACE