zoukankan      html  css  js  c++  java
  • 2019.11.12 跳石头

    题目背景

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

    题目描述

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

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

    输入格式

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

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

    输出格式

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

    输入输出样例

    输入 #1

    25 5 2 
    2
    11
    14
    17 
    21
    

    输出 #1

    4
    

    说明/提示

    输入输出样例 (1) 说明:将与起点距离为 (2)(14) 的两个岩石移走后,最短的跳跃距离为 (4) (从与起点距离 (17) 的岩石跳到距离 (21) 的岩石,或者从距离 (21) 的岩石跳到终点)。

    另:对于 (20\%)的数据,(0 leq M leq N leq 10)

    对于(50\%)的数据,(0 ≤ M ≤ N ≤ 100)

    对于 (100\%)的数据,(0 leq M leq N leq 50,000,1 leq L leq 1,000,000,000)

    容易想到二分答案。考虑如何(check)。贪心地找第一个比需要(check)的长度距目前位置距离大的石头并跳到该处,加上中间跳过的所有石头作为答案。

    注意在处理终点时,如果终点距离目前点的位置比需要(check)的长度小,则上次跳到这里的行为时不合法的,应当直接跳过该石头跳到终点,即答案(+1)

    上代码。注意上面那个地方有(10pts)分值。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<cctype>
    #define int long long
    #define rep(i,a,n) for(register int i=a;i<=n;i++)
    #define dep(i,n,a) for(register int i=n;i>=a;i--)
    using namespace std;
    int l,n,m,d[100050];
    inline int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	return x*f;
    }
    void write(int x)
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x==0)return;
    	write(x/10);
    	putchar('0'+x%10);
    }
    bool check(int len)
    {
    	int now=0;
    	int cnt=0;
    	rep(i,1,n-1)
    	{
    		if(d[i]-now>=len)now=d[i];
    		else ++cnt;
    		if(cnt>m)return false;
    	}
    	if(d[n]-now<len)++cnt;
    	if(cnt>m)return false;
    	return true;
    }
    signed main()
    {
    	l=read(),n=read(),m=read();
    	rep(i,1,n)d[i]=read();
    	d[n+1]=l;
    	++n;
    	int ll=1,rr=l;
    	while(ll<rr-1)
    	{
    		int mid=(ll+rr)>>1;
    		if(check(mid))ll=mid;
    		else rr=mid;
    	}
    	int ans;
    	if(check(rr))ans=rr;
    	else if(check(ll))ans=ll;
    	write(ans);
    	return 0;
    }
    
  • 相关阅读:
    MapReduce编程
    Xcode7 真机调试
    【学习笔记】【OC语言】NSString
    【学习笔记】【OC语言】多态
    【学习笔记】【OC语言】继承
    【学习笔记】【OC语言】self关键字
    【学习笔记】【OC语言】类方法
    【学习笔记】【OC语言】set方法和get方法
    【学习笔记】【OC语言】创建对象
    【学习笔记】【OC语言】面向对象思想
  • 原文地址:https://www.cnblogs.com/qxds/p/11844234.html
Copyright © 2011-2022 走看看