洛谷 P1542 【包裹快递】

一看到最小的最大就能知道是二分啦


对于这道题,我们要二分的值肯定是可以知道的:行驶速度,因为求的是速度,而边界条件就为\(0\)和最大的速度也就是路程总和了,对于精度,一般开在题目要求的精度上加\(4\)就行。\(cheak\)函数当然就是看以这个速度行走,能否到达终点即可。注意:题目虽然是说每一次的速度可以不一样,但是我们都按最大值的话,可以到达后等待一会儿,效果是一样的。能达到\(r\)就往\(mid\)移,缩小,反之。

知道了这些后,代码就好写了:

#include <bits/stdc++.h>
using namespace std;
struct node{
	double s , t , dis;	//起点 终点 距离 
};
int n;
double l , r , mid , eps = 1e-6;
node a[200010];
bool cheak(double speed){
	double time = 0;
	for(int i = 1; i <= n; i++){
		time += a[i].dis / speed;	//求时间 
		if(time < a[i].s){	//等待 
			time = a[i].s;
			continue;
		}
		if(time > a[i].t) return false;	//无法到达 
	}
	return true;
}
int main(){
	scanf("%d" , &n);
	for(int i = 1; i <= n; i++) scanf("%lf%lf%lf" , &a[i].s , &a[i].t , &a[i].dis) , r += a[i].dis;	//求上界 
	while(r - l > eps){
		mid = (l + r) / 2;
		if(cheak(mid)) r = mid;
		else l = mid;
	}
	printf("%.2f" , l);
	return 0;
}

交上去后,最后一个点被卡了对吧,是精度问题,于答案差\(0.01\),咋办?这时就要请出比double更厉害的类型,long double,所有都改成long double即可过。(注意,用scanf的话搭配的输入应该是scanf("%Lf"))。

AC代码:

#include <bits/stdc++.h>
using namespace std;
struct node{
	long double s , t , dis;
};
int n;
long double l , r , mid , eps = 1e-6;
node a[200010];
bool cheak(long double speed){
	long double time = 0;
	for(int i = 1; i <= n; i++){
		time += a[i].dis / speed;
		if(time < a[i].s){
			time = a[i].s;
			continue;
		}
		if(time > a[i].t) return false;
	}
	return true;
}
int main(){
	scanf("%d" , &n);
	for(int i = 1; i <= n; i++) scanf("%Lf%Lf%Lf" , &a[i].s , &a[i].t , &a[i].dis) , r += a[i].dis;
	while(r - l > eps){
		mid = (l + r) / 2;
		if(cheak(mid)) r = mid;
		else l = mid;
	}
	printf("%.2Lf" , l);
	return 0;
}
posted @ 2020-08-25 09:30  那一条变阻器  阅读(95)  评论(0编辑  收藏  举报