Vijos1450[包裹快遞] 二分答案

背景
小K成功地破解了密文。但是乘車到X國的時候,發現錢包被偷了,於是無奈之下只好作快遞員來攢足路費去Orz教主……
描述
一個快遞公司要將n個包裹分別送到n個地方,並分配給郵遞員小K一個事先設定好的路線,小K需要開車按照路線給的地點順序相繼送達,且不能遺漏一個地點。小K得到每個地方可以簽收的時間段,並且也知道路線中一個地方到下一個地方的距離。若到達某一個地方的時間早於可以簽收的時間段,則必須在這個地方停留至可以簽收,但不能晚於簽收的時間段,可以認爲簽收的過程是瞬間完成的。
爲了節省燃料,小K希望在全部送達的情況下,車的最大速度越小越好,就找到了你給他設計一種方案,並求出車的最大速度最小是多少。
格式
輸入格式
第1行爲一個正整數n,表示需要運送包裹的地點數。
下面n行,第i+1行有3個正整數xi,yi,si,表示按路線順序給出第i個地點簽收包裹的時間段爲[xi, yi],即最早爲距出發時刻xi,最晚爲距出發時刻yi,從前一個地點到達第i個地點距離爲si,且保證路線中xi遞增。
可以認爲s1爲出發的地方到第1個地點的距離,且出發時刻爲0。
輸出格式
僅包括一個整數,爲車的最大速度最小值,結果保留兩位小數。
樣例1
樣例輸入1
3
1 2 2
6 6 2
7 8 4
樣例輸出1
2.00
限制
對於20%的數據,n≤10;
對於30%的數據,xi,yi,si≤1000。
對於50%的數據,n≤1000;
對於100%的數據,n≤200000;


二分答案

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define db long double
const int maxn = 2e5;
struct P{
    int l, r, dis;
}a[maxn];

int n;

bool chk(db v){
    db p=0.0;
    for ( int i=1; i<=n; i++ ){
        p+=a[i].dis/v;
        //   printf("%.5lf\n", t);
        if( p>a[i].r ) return false;
        if( p<a[i].l ) p=(db)a[i].l;
    }
    return true;
}

int main(){
    scanf("%d", &n );
    for ( int i=1; i<=n; i++ )
        scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].dis);
    db L=0, R=2e8;
    while( R-L>=1e-6 ){
        db mid=(L+R)/2;
        if( chk(mid) ) R=mid;
        else L=mid;
    }
    printf("%.2Lf", L );
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章