zoukankan      html  css  js  c++  java
  • 迷宫 广搜

    【题目描述】
    山山来到了 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
    ",ans[n][m]);
    
    	return 0;
    }
    
    PEACE
  • 相关阅读:
    .NET Core前后端分离快速开发框架(Core.3.0+AntdVue)
    关于框架
    什么是 https ?这应该是全网把 https 讲的最好的一篇文章了
    NET手撸绘制TypeScript类图——下篇
    及时发现问题,力争找到更好的解决办法,而不是得过且过
    一个命令永久禁用Win10驱动程序强制签名
    表达式的结果为true或false
    Parcel 搭建浏览器自动刷新的 非 SPA项目
    Gulp 搭建前端非SPA 项目, 修改文件浏览器自动刷新
    vue 里 this.$parent 作用
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7677358.html
Copyright © 2011-2022 走看看