洛谷2678跳石头----二分答案入门

经典例题---跳石头

洛谷OJ P2678 跳石头

题目描述

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 NNN 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 MMM 块岩石(不能移走起点和终点的岩石)。

输入输出格式

输入格式:

第一行包含三个整数 L,N,ML,N,ML,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。保证 L≥1L \geq 1L≥1 且 N≥M≥0N \geq M \geq 0N≥M≥0。

接下来 NNN 行,每行一个整数,第 iii 行的整数 Di(0<Di<L)D_i( 0 < D_i < L)Di​(0<Di​<L), 表示第 iii 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。

输出格式:

一个整数,即最短跳跃距离的最大值。

数据范围

0≤ M ≤ N ≤ 50000

1 ≤ L ≤ 10000000000 ≤ M ≤ N ≤ 50000

1 ≤ L ≤ 1,0000000000 ≤ M ≤ N ≤ 50000

1≤ L ≤ 1000000000

类似求  最大值的最小值   最小值的最大值,都可以用二分答案来做。

这其实是一个暴力。暴力枚举检索答案,只不过在暴力枚举的时候,采用了二分优化,使得复杂度降低

这道题是一个二分入门  比较简单   这个二分答案吧  还是很有用的   思想要多理解

代码及注释

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=1e5+7;
int a[maxn],l,n,m;
bool check(int dis){//检测答案是否符合题意
    int conut=0,last=0;
    for(int i=1;i<=n;i++){
        if(a[i]-last<dis)conut++;//和前一个的距离小于dis的 就要移走
        else last=a[i];
    }
    if(conut>m)return false;//移动不能超过m次
    else return true;
}
int main(){
    scanf("%d%d%d",&l,&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int L=0,R=l,ans=0;
    while(L<=R){//二分查找答案   对于每一个答案  检测是否符合题意
        int mid=(L+R)/2;
        //满足题意的答案  我们继续往右找  因为这个题要找的是最小值的最大值
        if(check(mid))L=mid+1,ans=mid;
        else R=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/82431479