題目描述
小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≤10^8;si≤10^7。
樣例說明
第一段用1的速度在時間2到達第1個地點,第二段用0.5的速度在時間6到達第2個地點,第三段用2的速度在時間8到達第3個地點。
/**************************
Name:包裹快遞
How to get:luogu.org
By:Shine_Sky
**************************/
/*******************************
這道題 二分練習題
我只想吐槽
printf有毒!printf有毒!
printf有毒!printf有毒!
printf有毒!printf有毒!
*******************************/
#include<iostream>
#include<iomanip>
#include<cstdio>
#define ld long double
#define f(i,a,b) for(register int i=a;i<=b;i++)
#define fd(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
inline int read()
{
int data=0,w=1; char ch=0;
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
return data*w;
}
inline void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=200000+7;
int n=read(),sum;
struct A
{
int x,y,s;
}a[N];
inline bool pd(ld x)
{
ld t=0;
f(i,1,n)
{
t+=(ld)a[i].s/x;//到下一個地方所消耗時間加上
if(t<(ld)a[i].x) t=(ld)a[i].x;//要是提前到了就要等着
else if(t>(ld)a[i].y) return 0;//要是晚到了就答案錯誤
//要是就在這之前到了 沒影響 送完包裹向下一個走
}
return 1;
}
int main()
{
f(i,1,n) a[i].x=read(),a[i].y=read(),a[i].s=read(),sum+=a[i].s;
ld l=0,r=sum+2;
while((r-l)>1e-8)
{
ld Mid=(r+l)/2.0;
if(pd(Mid)) r=Mid;
else l=Mid;
}
cout<<fixed<<setprecision(2)<<l;
return 0;
}