noip2015跳石頭
阿新 • • 發佈:2018-11-02
題目背景
一年一度的“跳石頭”比賽又要開始了!
題目描述
這項比賽將在一條筆直的河道中進行,河道中分佈著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 N 塊岩石(不含起點和終點的岩石)。在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。
為了提高比賽難度,組委會計劃移走一些岩石,使得選手們在比賽過程中的最短跳躍距離儘可能長。由於預算限制,組委會至多從起點和終點之間移走 M 塊岩石(不能移走起點和終點的岩石)。
輸入輸出格式
輸入格式:
第一行包含三個整數 L,N,M,分別表示起點到終點的距離,起點和終點之間的岩石數,以及組委會至多移走的岩石數。保證 L≥1 且 N≥M≥0。
接下來 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%的資料,0≤M≤N≤10。
對於50%的資料,0≤M≤N≤100。
對於 100%的資料,0≤M≤N≤50,000,1≤L≤1,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大的數可能也成立,所以二分右部分的資料,反之分析左部分的資料。判斷是否成立的時候,就是遇到比他距離小的地方挪走石頭
如果要是挪走的數量大於給定的數量則不合法