C++ | 包裹快递问题 |题解

博客介绍了如何使用C++通过二分法和模拟解决快递包裹配送问题,找到在确保所有包裹送达情况下,最小的最大速度。文章包含题目描述、输入输出格式、样例解析及算法分析,强调了问题的单调性并提供了代码实现。
部署运行你感兴趣的模型镜像
 算法标签:二分、模拟

*备注:本题难度属于“提高/普及+”,难度稍大。

题目描述:        

小 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                         2.00
1 2 2
6 6 2
7 8 4

说明:

结果保留两位小数。

样例解释:

第一段用 1的速度在时间 2 到达第 1 个地点,第二段用 0.5 的速度在时间 6 到达第 2 个地点,第三段用 2 的速度在时间 8 到达第 3个地点。

——————————————————————————————————————————

分析题目:

1.要求的是最大速度的最小值

2.当我们到达一个地点的时候,还没到这个地点的签货时间,可以等到地点签货时间开始了再走

3.xi单调递增

很明显,我们可以全程保持着最大速度,这样可以更加的有机会抵达后面的,签货地点。

而且如果当速度为v的时候,可以抵达所以签货地点,那么当速度为(v+x)的时候,也可以抵达所有地点。所以这个问题是有单调性的,可以二分答案。具体细节看代码注释。

代码CODE:

#include <bits/stdc++.h>
#define double long double
using namespace std;
struct oi{
	double x,y,s;
}a[2000001];
int n;
bool check(double v){
	double t=0;
	for(int i=1; i<=n; i++){
		t=t+(double)(a[i].s)/(double)(v); //计算到下一个地方的最早的时间
		if(t>a[i].y) {//如果全程保持最大速度还来晚了,那就直接return 0;
			return 0;
		}
		if(t<a[i].x){//如果来早了,那就等到可以开始签收的时间再走
			t=a[i].x;
		}
	}
	return 1;
}
int main(){
	cin>>n;
	for(int i=1; i<=n; i++)	scanf("%LF%LF%LF",&a[i].x,&a[i].y,&a[i].s);
	double l=0,r=2e9;//二分速度
	while(l<=r){
		double mid=(l+r)/2;
		if(check(mid)){//如果当前速度有解,那么所有速度大于当前速度的数值就都有解,直接放弃那些数值,搜比当前数值更小的数值 所以是r=mid-(derla)
			r=mid-0.00001;
		} else l=mid+0.000001;
	}
	printf("%0.2LF",l);
	return 0;
} 

PWP

您可能感兴趣的与本文相关的镜像

Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值