包裹快递
题目描述
小 K 成功地破解了密文。但是乘车到 X 国的时候,发现钱包被偷了,于是无奈之下只好作快递员来攒足路费去 Orz 教主……
一个快递公司要将 n n n 个包裹分别送到 n n n 个地方,并分配给邮递员小 K 一个事先设定好的路线,小 K 需要开车按照路线给的地点顺序相继送达,且不能遗漏一个地点。小 K 得到每个地方可以签收的时间段,并且也知道路线中一个地方到下一个地方的距离。若到达某一个地方的时间早于可以签收的时间段,则必须在这个地方停留至可以签收,但不能晚于签收的时间段,可以认为签收的过程是瞬间完成的。
为了节省燃料,小 K 希望在全部送达的情况下,车的最大速度越小越好,就找到了你给他设计一种方案,并求出车的最大速度最小是多少。
输入格式
第 1 行为一个正整数 n n n,表示需要运送包裹的地点数。
下面 n n n 行,第 i + 1 i+1 i+1 行有 3 个正整数 x i , y i , s i x _ i, y _ i, s _ i xi,yi,si,表示按路线顺序给出第 i i i 个地点签收包裹的时间段为 [ x i , y i ] [x _ i, y _ i] [xi,yi],即最早为距出发时刻 x i x _ i xi,最晚为距出发时刻 y i y _ i yi,从前一个地点到达第 i i i 个地点距离为 s i s _ i si,且保证路线中 x i x _ i xi 递增。
可以认为 s 1 s _ 1 s1 为出发的地方到第 1 1 1 个地点的距离,且出发时刻为 0 0 0。
输出格式
仅包括一个正数,为车的最大速度最小值,结果保留两位小数。
样例 #1
样例输入 #1
3
1 2 2
6 6 2
7 8 4
样例输出 #1
2.00
提示
数据范围
- 对于 20 % 20\% 20% 的数据, 0 < n ≤ 10 0 < n \le 10 0<n≤10。
- 对于 30 % 30\% 30% 的数据, 0 < x i , y i , s i ≤ 1000 0<x_i,y_i,s_i \le 1000 0<xi,yi,si≤1000。
- 对于 50 % 50\% 50% 的数据, 0 < n ≤ 1000 0<n \le 1000 0<n≤1000。
- 对于 100 % 100\% 100% 的数据, 0 < n ≤ 2 × 1 0 5 0<n \le 2\times10^5 0<n≤2×105, x i ≤ y i ≤ 1 0 8 x_i \le y_i \le 10^8 xi≤yi≤108, s i ≤ 1 0 7 s_i \le10^7 si≤107。
样例解释
第一段用 1 1 1 的速度在时间 2 2 2 到达第 1 1 1 个地点,第二段用 0.5 0.5 0.5 的速度在时间 6 6 6 到达第 2 2 2 个地点,第三段用 2 2 2 的速度在时间 8 8 8 到达第 3 3 3 个地点。
大致思路
求解最大值最小之类的问题基本会用到二分来解决,此题也一样。
首先,我们要二分什么?
本题目需要求速度,二分速度即可
check函数如何写?
以mid为当前速度模拟送快递即可
以及二分模板,因为涉及到double的精度问题,不使用 l = m i d + 1 l=mid+1 l=mid+1 或 r = m i d − 1 r=mid-1 r=mid−1 这样的二分方式,而使用 l = m i d l=mid l=mid 及 r = m i d r =mid r=mid
坑点!!
必须使用long double才能ac
精度在1e-5及以下
long double的输出用%.2LF(大写)
AC CODE
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+2233;
long double l,r,mid,eps=1e-7;
int ans,n;
struct node{
int x,y,s;
}a[N];
bool check(double x){
long double now_time=0;
for(int i=1;i<=n;i++){
now_time+=a[i].s/x;
if(now_time>a[i].y)return 0;
if(now_time<a[i].x)now_time=a[i].x;
}
return 1;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].s);
}![请添加图片描述](https://img-blog.csdnimg.cn/8c1662828ac6442ab6b0cd559eb4d298.png)
l=0;r=1e8;
while(r-l>eps){
mid=(l+r)/2;
if(check(mid)){
r=mid;
}
else{
l=mid;
}
}
printf("%.2LF",l);
return 0;
}