P1542 包裹快递 (二分答案)(内附封面)

包裹快递

题目描述

小 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<n10
  • 对于 30 % 30\% 30% 的数据, 0 < x i , y i , s i ≤ 1000 00<xi,yi,si1000
  • 对于 50 % 50\% 50% 的数据, 0 < n ≤ 1000 00<n1000
  • 对于 100 % 100\% 100% 的数据, 0 < n ≤ 2 × 1 0 5 00<n2×105 x i ≤ y i ≤ 1 0 8 x_i \le y_i \le 10^8 xiyi108 s i ≤ 1 0 7 s_i \le10^7 si107

样例解释

第一段用 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=mid1 这样的二分方式,而使用 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
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;
}

附封面(恋爱暴走机车)

P1542 包裹快递 (二分答案)(内附封面)_第1张图片

你可能感兴趣的:(c++,算法)