信息学奥赛一本通(1247:河中跳房子)
1247:河中跳房子
時間限制: 1000 ms ??? ??? 內存限制: 65536 KB
提交數: 5287 ??? 通過數: 2522
【題目描述】
每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河里從一個巖石跳到另一個巖石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點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)。
【分析】
? ? ? ? 采用二分法,最短距離最大。二分時,如果中間值可行,繼續猜后一半,對于一個答案m,如果可行,那么相鄰石頭之間的距離都不小于m,也就是如果出現小于m的,那個石頭必須移走。寫一個函數判斷當前答案需要移走多少塊石頭,如果不超過k塊,那就可以,否則不行。
? ? ? ? 初始left=0,right=25,distance=12,去掉兩個石頭,剩四個區間,我們的問題就是找一個最大的distance,使得這四段區間距離都不小于distance。即最短距離最大。
? ? ? ? 如果distance=12,那么在從14向后繼續找,發現找不到第二顆石頭,調整區間left和right,以此類推,繼續查找。
【參考代碼】
#include <stdio.h> #define N 50010 int blocks[N]; int check(int n,int distance) {int now=0,cnt=0,i;for(i=1;i<=n+1;i++){if(blocks[i]-blocks[now] >= distance){cnt++;now=i;}}return cnt; } int main() {int i,l,n,m;int left,right,distance,ans;scanf("%d%d%d",&l,&n,&m);for(i=1;i<=n;i++)scanf("%d",&blocks[i]);blocks[n+1]=l;left=0;right=l;while(left<=right){distance=(left+right)/2;if(check(n,distance)>=n-m+1){ans=distance;left=distance+1;}else{right=distance-1;}}printf("%d\n",ans);return 0; }http://ybt.ssoier.cn:8088/problem_show.php?pid=1247
總結
以上是生活随笔為你收集整理的信息学奥赛一本通(1247:河中跳房子)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信息学奥赛一本通(1323:【例6.5】
- 下一篇: 信息学奥赛一本通 1059:求平均年龄