• 4768 跳石头


    4768 跳石头

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 黄金 Gold
     
     
    题目描述 Description

    一年一度的“跳石头”比赛又要开始了! 

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

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

    输入描述 Input Description

    输入文件名为 stone.in。 

    输入文件第一行包含三个整数L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。 

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

    输出描述 Output Description

    输出文件名为stone.out。 

    输出文件只包含一个整数,即最短跳跃距离的最大值。

    样例输入 Sample Input

    25 5 2

    11 

    14 

    17

    21

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

    对于20%的数据,0≤M≤N≤10。 对于50%的数据,0≤M≤N≤100。 

    对于50%的数据,0≤M≤N≤100。

    对于100%的数据,0≤M≤N≤50,000,1≤L≤1,000,000,000。

    分类标签 Tags 

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int a[50010],L,m,n;
    int check(int x){
        int p=0,ans=0;//p为前一个石头到指向石头的距离的下标 
        for(int i=1;i<=n;i++){
            if(a[i]-a[p]<x){//如果第i个石头到前一个石头的距离小于假设的答案 
                ans++; //该石头可以搬走 
            }
            else{//如果大于(即满足条件) 
                p=i;//则保留该石头,并将p记录该石头的下标以便计算下一个石头到它的距离 
            }
        }
        return ans<=m;
    }
    int main(){
        scanf("%d%d%d",&L,&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",a+i);
        }
        a[++n]=L;//我们假设在终点处有第n+1个石头,则他到起点的距离为L 
        int l=1,r=L+1;//r要注意+1,下面二分可能搜不到右端点 
        while(l+1<r){
            int mid=(l+r)/2;
            if(check(mid)) l=mid;//说明二分结果小了,要向右二分
            else r=mid;//说明结果大了,要向左二分
        }
        printf("%d
    ",l);
        return 0;
    } 

     重新写了一遍,印象更深

    #include<cstdio>
    using namespace std;
    #define N 100010
    int n,m,len,d[N];
    bool check(int x){
        int res=0,p=0;
        for(int i=1;i<=n;i++){
            if(d[i]-p<=x)
                res++;
            else
                p=d[i];
        }
        return res<=m;
    }
    int main(){
        scanf("%d%d%d",&len,&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&d[i]);
        int l=1,r=len,mid;
        while(l<r){
            mid=(l+r>>1);
            if(check(mid)) l=mid+1;
            else r=mid;
        }
        printf("%d",l);
        return 0;
    }
  • 相关阅读:
    剑指offer——最小的K个数和数组中第K大的元素
    Leetcode刷题指南链接整理
    160. Intersection of Two Linked Lists
    100. Same Tree
    92. Reverse Linked List II
    94. Binary Tree Inorder Traversal
    79. Word Search
    78,90,Subsets,46,47,Permutations,39,40 DFS 大合集
    0x16 Tire之最大的异或对
    0x16 Tire
  • 原文地址:https://www.cnblogs.com/shenben/p/5557708.html
Copyright © 2020-2023  润新知