c 二分答案 之 跳石頭

2022-05-30 01:57:11 字數 1769 閱讀 5655

題目:

題目描述 description

一年一度的「跳石頭」比賽又要開始了! 

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

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

輸入描述 input description

輸入檔名為 stone.in。 

輸入檔案第一行包含三個整數l,n,m,分別表示起點到終點的距離,起點和終點之間的岩石數,以及組委會至多移走的岩石數。 

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

輸出描述 output description

輸出檔名為stone.out。 

輸出檔案只包含乙個整數,即最短跳躍距離的最大值。

樣例輸入 sample input

25 5 2

2 11 

14 樣例輸出 sample output

資料範圍及提示 data size & hint

對於20%的資料,0≤m≤n≤10。 對於50%的資料,0≤m≤n≤100。 

對於50%的資料,0≤m≤n≤100。

對於100%的資料,0≤m≤n≤50,000,1≤l≤1,000,000,000。

咋說呢,這題一開始看覺得:哎呀,肯定動規。然後看資料:10^9,然後瞬間懵逼了。於是上網查:要用個東西叫做……二分答案。

先上**再解釋:

#include using

namespace

std;

int l,n,m,a[50005

],ans;

bool check(int

dis)

intmain()

cout

}

嗯,啥意思呢?輸入我就不講了,然後這個fl,fr是什麼呢?

二分查詢肯定會吧?【不會的先洗洗睡吧別往下看了】這個fl,fr就是查詢答案的範圍的左邊界和右邊界。查詢啥呢?都說了是二分答案,你說二分啥?二分距離唄。意思是我們現在要找到乙個最大值的距離,這個距離能保證只搬走m或m以內個石頭就能讓任意兩個相鄰的石頭之間的距離≥這個距離。我們就來二分查詢滿足這個條件的最大的距離。

先是從0~l之間查詢這個距離,取中間值,也就是l/2,然後看l/2這個距離是否滿足上面那個條件,如果滿足那個條件,就把二分查詢的左邊界調到中間值(也就是l/2)的右邊乙個去,這樣再次查詢的範圍就排除了不可能存在最優解的左半邊(因為左半邊所有滿足或者不滿足上面那個條件的所有距離都會小於l/2這個距離,所以不可能存在(不然為啥不選l/2這個值呢?l/2也滿足那個條件啊)),並且在這裡還要記住中間值,因為他是目前的最優解。如果中間值(當前是l/2)不滿足那個條件,那l/2的右邊的所有距離也都不可能存在某個距離能滿足那個條件了(要不然l/2也會滿足那個條件的,對吧?),所以就把查詢的右邊界調到中間值的左邊乙個去。

當我們處理完上一步後,就得到了乙個新的查詢區間——原區間的左半邊或者右半邊。再在這個查詢區間用上面的方法查詢,直到區間裡沒有數字了,查詢結束。輸出答案。

附上二分答案模板:

int l,r,mid,ans;

while(l<=r)

跳石頭 二分答案

題目背景 一年一度的 跳石頭 比賽又要開始了 題目描述 這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 nnn 塊岩石 不含起點和終點的岩石 在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。為了提高...

C 跳石頭題解(二分答案)

跳石頭 描述一年一度的 跳石頭 比賽又要開始了 這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 n塊岩石 不含起點和終點的岩石 在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。為了提高比賽難度,組委...

二分 跳石頭

一定要學好程式設計。一年一度的 跳石頭 比賽又要開始了 這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選 擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 n 塊岩石 不含起點和終 點的岩石 在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達 終點。為了提...