跳石头

跳石头【noip2015】

题目描述

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

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

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

输入格式

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

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

输出格式

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

样例一

input

25 5 2
2
11
14
17
21

output

4

explanation

将与起点距离为 2和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。

限制与约定

测试点编号n,m的规模L的规模
1 n,m10
L10^9
2
3 n,m100
4
5
6 n,m50000
7
8
9
10

时间限制:1s

空间限制:128MB

 二分答案:问法:最小的要最大,最大的要最小,问什么二分什么,确定一个答案,挨个枚举,然后还有一个数据作为限制条件,看看我们假设的答案是否正确。

本题问最小距离的最大,那么我们假定一个答案为距离的中间值(问什么分什么),然后枚举,如果比这个值小,那么移动石头,否则继续查看,本题目的限制条件就是移动的石头数目,看看是否符合要求。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<iomanip>
 5 using namespace std;
 6 const int maxx=5010;
 7 int a[maxx];
 8 int L,n,m,ans,r,l;
 9 bool check(int);//查看这个距离是否是可以走的最小距离 
10 int main()
11 {
12     scanf("%d%d%d",&L,&n,&m);
13     for(int i=1;i<=n;i++)
14     scanf("%d",&a[i]);//输入到起点的距离 
15     int r=L;
16     while(l<=r)
17     {
18     int mid=l+(r-l)/2;//可以避免(l+r)/2中数据过大 
19         if(check(mid))//当最小距离是mid时 
20         {
21           ans=mid;//记录答案 
22           l=mid+1;    //继续向中间以后的大数据找,说不定还可以跳更远 
23         }
24         else
25         r=mid-1;//中间距离没法跳,说明跳远了,再试小数据 
26     }
27     printf("%d",ans);//输出答案 
28     return 0;
29 }
30 bool check(int x)
31 {
32     int sum=0,last=0;
33     for(int i=1;i<=n;i++)
34     {
35         if(a[i]-last<x)//当距离小于我们确定的最小距离时,移走石头 
36         {sum++;continue;}
37          last=a[i];//如果不移动,当前石头记录为下一个石头的上一个石头 
38     }
39     if(sum>m)return 0;//移动的石头数大于m说明 跳远了 
40     else return 1;
41 }
原文地址:https://www.cnblogs.com/zzyh/p/6625343.html