洛谷P1542 包裹快遞(二分+模擬)

題目描述
小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 複製
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;xi≤yi≤108;si≤107。

時限1s

第一段用1的速度在時間2到達第1個地點,第二段用0.5的速度在時間6到達第2個地點,第三段用2的速度在時間8到達第3個地點。
題目分析:
像這種確定最大值最小值哪個最合適的題並且知道答案範圍的都可以用二分來一個個的試答案,看看哪個最合適。而這個題答案的範圍很明顯,從0開始到1e7結束,這個題還對精度有很大的要求,以前從沒做過這種,也算是擴展自己的知識面了吧。
代碼:

#include<iostream>
#include<iomanip>
using namespace std;
const int N=2e5+10;
int n;
typedef long double ld;
struct time{
  double l,r,s;
}t[N];
bool judge(ld x)
{
    ld tot=0;//總時間
    for(int i=1;i<=n;i++)
    {
        tot+=t[i].s/x;//加上到這個點所需的時間
        if(tot>t[i].r) return false;//去晚了,直接返回
        if(tot<t[i].l) tot=t[i].l;//去早了,那就等到人來
    }
    return true;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>t[i].l>>t[i].r>>t[i].s;
    }
    ld left=0;
    ld right=1e7,mid,ans;
    while(right-left>=0.000001)//注意精度
    {
        mid=(left+right)/2;
        if(judge(mid)) {
            ans=mid;//儲存答案
            right=mid;//速度合適那就嘗試更小的值,因爲題目要求確定最大值最小是多少
        }
        else {
            left=mid;//速度不合適那就嘗試更大的值。
        }
    }
    cout<<fixed<<setprecision(2)<<ans<<endl;//兩位小數
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章