洛谷—— P2658 汽车拉力比赛

https://www.luogu.org/problem/show?pid=2658

题目描述

博艾市将要举行一场汽车拉力比赛。

赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间。

其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D。也就是说这个难度系数D指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。

输入输出格式

输入格式:

第一行两个整数M和N。第2行到第M+1行,每行N个整数描述海拔高度。第2+M行到第1+2M

行,每行N个整数,每个数非0即1,1表示该单元格是一个路标。

输出格式:

一个整数,即赛道的难度系数D。

输入输出样例

输入样例#1:

3 5
20 21 18 99 5
19 22 20 16 26
18 17 40 60 80
1 0 0 0 1
0 0 0 0 0
0 0 0 0 1

输出样例#1:

21

二分一个最小差值,bfs验证是否可以遍历全部路标
 1 #include <cstring>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <queue>
 5
 6 #define max(a,b) (a>b?a:b)
 7 inline void read(int &x)
 8 {
 9     x=0; register char ch=getchar();
10     for(; ch>‘9‘||ch<‘0‘; ) ch=getchar();
11     for(; ch>=‘0‘&&ch<=‘9‘; ch=getchar()) x=x*10+ch-‘0‘;
12 }
13 const int N(555);
14 int n,m,h[N][N],cnt;
15 int go[N][N],sx,sy;
16
17 bool vis[N][N];
18 int fx[4]={0,1,0,-1};
19 int fy[4]={1,0,-1,0};
20 struct Node {
21     int x,y;
22     int cnt;
23 }u,v;
24 int l,r,mid,ans;
25 inline bool check(int x)
26 {
27     int ret=1;
28     std::queue<Node>que;
29     memset(vis,0,sizeof(vis));
30     u.cnt=1; u.x=sx; u.y=sy;
31     que.push(u); vis[sx][sy]=1;
32     for(; !que.empty(); que.pop())
33     {
34         u=que.front();
35         if(ret==cnt) return 1;
36         for(int i=0; i<4; ++i)
37         {
38             v.x=u.x+fx[i];
39             v.y=u.y+fy[i];
40             if(vis[v.x][v.y]||v.x>n||v.y>m||v.x<1||v.y<1) continue;
41             if(abs(h[u.x][u.y]-h[v.x][v.y])<=x)
42             {
43                 que.push(v),vis[v.x][v.y]=1;
44                 if(go[v.x][v.y]) ret++;
45             }
46         }
47     }
48     return 0;
49 }
50
51 int Presist()
52 {
53     read(n),read(m);
54     for(int i=1; i<=n; ++i)
55       for(int j=1; j<=m; ++j)
56         read(h[i][j]),r=max(r,h[i][j]);
57     for(int x,i=1; i<=n; ++i)
58       for(int j=1; j<=m; ++j)
59       {
60           read(go[i][j]);
61         if(go[i][j])
62           { cnt++;sx=i;sy=j; }
63       }
64     for(; l<=r; )
65     {
66         mid=l+r>>1;
67         if(check(mid))
68         {
69             ans=mid;
70             r=mid-1;
71         }
72         else l=mid+1;
73     }
74     printf("%d\n",ans);
75     return 0;
76 }
77
78 int Aptal=Presist();
79 int main(int argc,char*argv[]){;}
时间: 2024-12-17 16:31:11

洛谷—— P2658 汽车拉力比赛的相关文章

洛谷——P2658 汽车拉力比赛

P2658 汽车拉力比赛 题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些单元格被定义为路标.组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D.也就是说这个难度系数D指的是保证所有路标相互可达的最小值.任一单元格和其东西南北四个方向上的单元格都是相邻的. 输入输出格式 输入格式: 第一行两个整数M和N

洛谷2658 汽车拉力比赛

本题地址:http://www.luogu.org/problem/show?pid=2658 题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些单元格被定义为路标.组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D.也就是说这个难度系数D指的是保证所有路标相互可达的最小值.任一单元格和其东西南北四个方向

P2658 汽车拉力比赛

题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些单元格被定义为路标.组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D.也就是说这个难度系数D指的是保证所有路标相互可达的最小值.任一单元格和其东西南北四个方向上的单元格都是相邻的. 输入输出格式 输入格式: 第一行两个整数M和N.第2行到第M+1行,每行

洛谷 P2965 [USACO09NOV]农活比赛The Grand Farm-off

P2965 [USACO09NOV]农活比赛The Grand Farm-off 题目描述 Farmer John owns 3*N (1 <= N <= 500,000) cows surprisingly numbered 0..3*N-1, each of which has some associated integer weight W_i (1 <= W_i <= d). He is entering the Grand Farm-off, a farming comp

洛谷 1707 刷题比赛

/* 矩阵稍微有点难搞 不过也是可以推出来 注意防爆... */ #include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; ll n,mod,p,q,r,t,u,v,w,x,y,z; ll f[12][12],a[12][12]; ll slow_mul(ll a,ll b) { ll ans=0; while(b) { if(b&

归并排序求逆序对 //(洛谷)U4566 赛车比赛

https://www.luogu.org/problem/show?pid=U4566 显然的逆序对,以前只是嘴巴ac,这次终于打了出来. 逆序对其实就是冒泡排序的排序次数....但是一般的排序时间复杂度为O(n^2),于是都会想到归并排序... 一.二路归并 已知两个有序数组,将其归并为一个有序数组 很显然,将首元素比较,小的扔进目的数组,最后把剩下的扔进去.. 1 int a[n],b[m],tmp[n+m]; 2 int i=1,j=1,k=1; 3 while(i<=n&&

洛谷 P4009 汽车加油行驶问题 【最小费用最大流】

分层图,建k层,设(i,j,0)为点(i,j)的满油状态,全图的流量都是1,因为重复走到一个点没有意义.如果当前点是加油站,那么它向它上左的点连费用为a的边,向下右连费用为a+b的边: 否则,这个点的所有层向零层连费用为a+c的边表示建加油站和加油,其他的当前点是加油站的情况连即可,但是不用加a.然后s向(1,1,0)连,(n,n)的所有层向t连,最后跑最小费用最大流. #include<iostream> #include<cstdio> #include<cmath>

[无聊测试赛] T4 汽车拉力比赛

这题有两个思路,第一个是并查集,第二是二分.我写的二分,复杂度 \(O(n^2logn)\) 可以过 二分的方法:二分高度差别.然后从某个点起点开始整个图.如果能够将所有起点覆盖,那么证明这个高度可以实现 遍历图可以用bfs实现.这题码量稍大,但思路清晰 #include <iostream> #include <algorithm> #include <queue> using namespace std; #define pp pair<int,int>

[题解]洛谷比赛『期末考后的休闲比赛2』

[前言] 这场比赛已经结束了有几天,但我各种忙,虽然AK但还是没来得及写题解.(我才不会告诉你我跑去学数据结构了) T1 区间方差 (就不贴题好了) 首先可以推公式(我们可以知道,线段树然而并不能通过初中学过的方差公式在log(L)内求出方差): (s2表示方差,L表示区间长度,xi表示区间的每一项,最后一个x上画了一根线表示这些数据的平均数) 用二项式定理完全平方公式可得: 再次展开: 另外,再代入以下这个 得到了: 然后继续吧.. 然后duang地一声合并同类项,于是我们得到了: 然后可以高