1. 程式人生 > >River Hopscotch [二分]

River Hopscotch [二分]

題意:馬跳石頭,給定石頭的位置,求拿掉m個石頭後,馬到目的地過程中跳躍的最小距離的最大值。
思路:給定的石頭位置,初始0,目的地L, 排個序。然後二分最小距離找最大值。
二分的單調性:如果馬的最小一步能跨越l,那麼對於任意的li>l作為最小步長都是合理的。
二分的check(mid):如果當前最小步長mid滿足僅有cnt<=m個小於mid的長度時,以當前mid作為最小步長是可行的。

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm> #include<map> #include<set> #include<queue> #include<vector> #include<cstdlib> #include<list> #include<stack> #include<cmath> #include<iomanip> using namespace std; //#pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long
LL; void debug() {cout << "ok running!" << endl;} int a[100005]; int m, n, L; bool check(int mid) { int cnt = 0; for(int i = 0; i <= n; ++i) { int temp = a[i]; while(a[i+1] - temp < mid && i <= n) { cnt++; i++; } } if
(cnt <= m) { return 1; } else return 0; } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); #endif // ONLINE_JUDGE while(cin >> L >> n >> m) { a[0] = 0; a[n+1] = L; for(int i = 1; i <= n; ++i) cin >> a[i]; sort(a, a+n+1); int l = 0, r = L; int ans = -1; while(l <= r) { int mid = (l+r) >> 1; if(check(mid)) { l = mid+1; ans = mid; } else r = mid-1; } cout << ans << endl; } return 0; }