NKOI3600 河中跳房子遊戲

2021-08-15 07:40:38 字數 2119 閱讀 5017

[二分答案]

題目描述

每年,奶牛們都舉辦一種特殊的跳房子遊戲,在這個遊戲中,大家小心翼翼地在河中的岩石上跳。這個遊戲在一條筆直的河中進行,以一塊岩石表示開始,以另一塊距離起點l單位長度的岩石表示結束 (1 <= l <= 1,000,000,000)。在這兩塊岩石中間還有n(0 <= n <= 50,000) 塊岩石,每塊的位置距離起點是 di (0 < di < l)個單位長度。

玩這個遊戲的時候,每頭牛從開始的那塊岩石想辦法要跳到表示結束的那塊岩石上。中間只能在從某塊岩石跳躍到另一塊岩石,反覆的這樣跳。當然,不夠敏捷的牛永遠跳不到終點,最終只能落入河中。fj計畫移除一些岩石,從而增加奶牛在跳躍時需要的最短距離。他不能移除開始和結束的兩塊岩石。但是除此之外他可以移除 m (0 <= m <= n)塊岩石。fj 希望知道他能夠增加多少最短跳躍距離。求當他移除了m塊岩石後,奶牛從開始跳到結束的岩石,每次跳躍的最短距離至多可以增加到多少。

輸入格式

行 1: 三個用空格分開的整數,分別是 l, n, 和 m

行 2..n+1: 每行乙個整數,表示中間n塊岩石的位置,沒有兩塊岩石處於同一位置。

輸出格式

行 1: 乙個整數表示移除某m塊岩石後,相鄰岩石間距最小值的最大可能情況。

這道題顯然應該先按每個點到起點的距離

增加最短距離,最小值最大釋放了二分答案的訊號。

按照一般步驟:

1.確定上下界

下界就是題目中給出的最短距離,或者直接設為0也可以。

上界就是起點到終點的距離(fj喪心病狂地拿走了起點到終點間的所有石頭)。

2.二分 [ok()函式咋寫]

大體的思路很簡單:使每個點之間的距離d大於等於二分的答案mid即可。

↓偽**實現↓

現在已經有了乙個排好序的陣列dis[n],用來存每個點到起點的距離.

相鄰點相減的值,就是d.

由於原陣列dis[n]要重複使用,所以另外開乙個新陣列tmp[n]充當dis[n].

for(int i=1;i<=n;i++)tmp[i]=dis[i];

只要d小於我們二分的答案mid,就繼續拿走石頭(計數器t加1).

最後判斷:如果t>m,那麼說明mid大了,減小mid的值才能使移除石頭的數量減少;反之,t<=m,就說明mid小了(剛好合適),要增大mid的值才能增加移除石頭的數量.

注意

最後判斷的時候,每道題都有不同的方法,特別要注意是「<」or」<=」,「>」or」>=」.千萬不要錯!不然==樣例都過不了[乙隻蒟蒻的心聲]==

所以,合起來,**如下:

#include

#include

#include

#define n 60000

#define ll long long

using

namespace

std;

ll dis[n],tmp[n];

bool ok(ll mid)

}if(t>m)return

true;

else

return

false;

}int main()

//注意最後還要判斷一下l和r哪個才是正解

//如果ok(l)==true,說明l對應的移除石頭的數量比要求的要多,應捨去

if(ok(l))printf("%lld",r);

else

printf("%lld",l);return

0;}

河中跳房子

時間限制 1 sec 記憶體限制 128 mb 25 5 2211 1417 214 總時間限制 1000ms 記憶體限制 65536kb 描述每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河裡從乙個岩石跳到另乙個岩石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點l遠 1 l 1...

河中跳房子

時間限制 1000 ms 記憶體限制 65536 kb 提交數 485 通過數 227 每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河裡從乙個岩石跳到另乙個岩石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點l遠 1 l 1,000,000,000 的終點處均有乙個岩石。在起點和...

1247 河中跳房子

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