1. 程式人生 > >河中跳房子

河中跳房子

clu 有一個 特殊 php spa span iostream 最長 時間

河中跳房子

鏈接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1247
時間限制: 1000 ms 內存限制: 65536 KB

【題目描述】

每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河裏從一個巖石跳到另一個巖石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點L遠 (1 ≤ L≤ 1,000,000,000) 的終點處均有一個巖石。在起點和終點之間,有N (0 ≤ N ≤ 50,000) 個巖石,每個巖石與起點的距離分別為Di (0 < Di < L)。

在比賽過程中,奶牛輪流從起點出發,嘗試到達終點,每一步只能從一個巖石跳到另一個巖石。當然,實力不濟的奶牛是沒有辦法完成目標的。

農夫約翰為他的奶牛們感到自豪並且年年都觀看了這項比賽。但隨著時間的推移,看著其他農夫的膽小奶牛們在相距很近的巖石之間緩慢前行,他感到非常厭煩。他計劃移走一些巖石,使得從起點到終點的過程中,最短的跳躍距離最長。他可以移走除起點和終點外的至多M (0 ≤ M ≤ N) 個巖石。

請幫助約翰確定移走這些巖石後,最長可能的最短跳躍距離是多少?

【輸入】

第一行包含三個整數L, N, M,相鄰兩個整數之間用單個空格隔開。

接下來N行,每行一個整數,表示每個巖石與起點的距離。巖石按與起點距離從近到遠給出,且不會有兩個巖石出現在同一個位置。

【輸出】

一個整數,最長可能的最短跳躍距離。

【輸入樣例】

25 5 2
2
11
14
17
21

【輸出樣例】

4

【提示】

在移除位於2和14的兩個巖石之後,最短跳躍距離為4(從17到21或從21到25)。

題解:先二分找到最長距離,然後貪心最短的最長距離

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[50005],b[50005],p[50005];
const int MAXN=1000000005;
int main()
{
    int L,n,m,l=MAXN;
    cin>>L>>n>>m;
    for
(int i=1;i<=n;i++) { cin>>a[i]; b[i]=a[i]-a[i-1]; l=min(l,b[i]); } b[n+1]=L-a[n];b[0]=MAXN; int r=2*L; while(l+1<r) { for(int i=1;i<=n+1;i++)p[i]=b[i]; int mid=(l+r)/2,cnt=0; for(int i=1;i<=n+1;i++) if(p[i]>=mid); else {p[i+1]+=p[i];cnt++;} if(cnt>m)r=mid; else l=mid; } int cnt=0,ans,t=0; for(int i=1;i<=n+1;i++)p[i]=b[i]; for(int i=1;i<=n+1;i++) if(p[i]>=r); else {p[i+1]+=p[i];cnt++;} if(cnt==m)ans=r; else ans=l; for(int i=1;i<=n+1;i++) if(b[i]>=ans); else {   if(b[i-1]>b[i+1])b[i+1]+=b[i]; else b[i-1]+=b[i]; b[i]=MAXN; } int minn=MAXN; for(int j=1;j<=n+1;j++) minn=min(minn,b[j]); cout<<minn<<endl; }

河中跳房子