博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迷宫 广搜
阅读量:5134 次
发布时间:2019-06-13

本文共 2362 字,大约阅读时间需要 7 分钟。

【题目描述】

山山来到了 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
#include
#include
#include
#include
#define ll long long#define il inline#define db doubleusing 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;}

 

转载于:https://www.cnblogs.com/gshdyjz/p/7677358.html

你可能感兴趣的文章
django+uwsgi+nginx+sqlite3部署+screen
查看>>
浅谈项目需求变更管理
查看>>
经典算法系列一-快速排序
查看>>
设置java web工程中默认访问首页的几种方式
查看>>
ASP.NET MVC 拓展ViewResult实现word文档下载
查看>>
8、RDD持久化
查看>>
第二次团队冲刺--2
查看>>
Linux上架设boost的安装及配置过程
查看>>
[转载]加密算法库Crypto——nodejs中间件系列
查看>>
使用Xshell密钥认证机制远程登录Linux
查看>>
Android 画图之 Matrix(一)
查看>>
【模板】最小生成树
查看>>
设计模式之结构型模式
查看>>
poj2569
查看>>
使用pygal_maps_world.i18n中数据画各大洲地图
查看>>
jQuery EasyUI 的下拉选择combobox后台动态赋值
查看>>
timeline时间轴进度“群英荟萃”
查看>>
python if else elif statement
查看>>
网络编程
查看>>
文本隐藏(图片代替文字)
查看>>