1. 程式人生 > >noip2015跳石頭

noip2015跳石頭

題目背景

一年一度的“跳石頭”比賽又要開始了!

題目描述

這項比賽將在一條筆直的河道中進行,河道中分佈著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 N 塊岩石(不含起點和終點的岩石)。在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。

為了提高比賽難度,組委會計劃移走一些岩石,使得選手們在比賽過程中的最短跳躍距離儘可能長。由於預算限制,組委會至多從起點和終點之間移走 M 塊岩石(不能移走起點和終點的岩石)。

輸入輸出格式

輸入格式:

 

第一行包含三個整數 L,N,M,分別表示起點到終點的距離,起點和終點之間的岩石數,以及組委會至多移走的岩石數。保證 L1 且 NM0。

接下來 N 行,每行一個整數,第 i 行的整數 Di(0<Di<L), 表示第 i 塊岩石與起點的距離。這些岩石按與起點距離從小到大的順序給出,且不會有兩個岩石出現在同一個位置。

 

輸出格式:

 

一個整數,即最短跳躍距離的最大值。

 

輸入輸出樣例

輸入樣例#1: 複製
25 5 2 
2
11
14
17 
21
輸出樣例#1: 複製
4

說明

輸入輸出樣例 1 說明:將與起點距離為 2和 14 的兩個岩石移走後,最短的跳躍距離為 4(從與起點距離 17 的岩石跳到距離 21 的岩石,或者從距離 21 的岩石跳到終點)。

另:對於 20%的資料,0MN10。

對於50%的資料,0MN100。

對於 100%的資料,0MN50,000,1L1,000,000,000。

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int i,j,m,n;
 7 long long int l,r,mid,ans,lo,d[50005];
 8 bool panduan(int x)
 9 {
10 int op = 0; 11 int t = 1; 12 for(i = 2;i <= n + 1;i++) 13 { 14 if(d[i] - d[t] < x) 15 op++; 16 else 17 t = i; 18 if(op > m) 19 break; 20 } 21 if(op > m) 22 return false; 23 else 24 return true; 25 } 26 int main() 27 { 28 scanf("%lld %d %d",&lo,&n,&m); 29 d[1] = 0; 30 for(i = 2;i <= n + 1;i++) 31 { 32 scanf("%lld",&d[i]); 33 } 34 l = 1; 35 r = lo; 36 while(l <= r) 37 { 38 mid = (l + r) / 2; 39 if(panduan(mid) == 1) 40 { 41 l = mid + 1; 42 ans = mid; 43 } 44 else 45 r = mid - 1; 46 } 47 printf("%lld",ans); 48 return 0; 49 }

*****這道題是二分,二分成立的最小距離的最大值,如果mid成立則mid大的數可能也成立,所以二分右部分的資料,反之分析左部分的資料。判斷是否成立的時候,就是遇到比他距離小的地方挪走石頭

如果要是挪走的數量大於給定的數量則不合法