算法入门-传送带(三分典例)

【入门班】急速行走

https://ac.nowcoder.com/acm/problem/20276

题意

  • 两条传送带AB,CD,给出四个点坐标,在两条传送带和地面上的速度分别为P,Q,R,从A到D的最短时间是多少?

思路

  • 从AB到CD某点花费满足凹函数,从AB某点到CD花费也满足凹函数,三分套三分

AC代码

#include<bits/stdc++.h>
using namespace std;
int P,Q,R;
const double eps=1e-7;
typedef struct{
	double x,y;
}dt;
dt A,B,C,D,E,F;

double dis(dt a,dt b){
	return sqrt(eps+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cal2(double a,double b){
	E.x = A.x + (b / dis(A,B)) * (B.x - A.x);
	E.y = A.y + (b / dis(A,B)) * (B.y - A.y);
	F.x = C.x + (a / dis(C,D)) * (D.x - C.x);
	F.y = C.y + (a / dis(C,D)) * (D.y - C.y);
	return (dis(C,D)-a)/Q+b/P+dis(E,F)/R;
}

double cal1(double a){
	double l=0,r=dis(D,C);
	int t=100;
	while(t--){
		double m1 = l + (r - l)/3;
		double m2 = r - (r - l)/3;
		if(cal2(m1,a)<cal2(m2,a)){
			r=m2;
		}else{
			l=m1;
		}
	}
	return cal2(l,a);
}

int main(){
	scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y,&D.x,&D.y);
	scanf("%d%d%d",&P,&Q,&R);
	//三分套三分
	double l=0,r=dis(A,B);
	int t=100;
	while(t--){
		double m1=l+(r-l)/3;
		double m2=r-(r-l)/3;
		if(cal1(m1)<cal1(m2)){
			r=m2;
		}else{
			l=m1;
		}
	}
	printf("%.2lf\n",cal1(l));
	return 0;
}

PS

  • 这个题真是极其恶心,把人都给debug傻了,注意计算各种距离即可
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-07 18:05
哈哈哈哈哈感觉朋友找工作的已经疯掉了,直接上图
码农索隆:真老板娘:“我嘞个去,这不我当年的套路吗
点赞 评论 收藏
分享
07-03 16:02
门头沟学院 Java
点赞 评论 收藏
分享
06-23 11:28
门头沟学院 Java
牛客91966197...:也有可能是点拒绝的时候自动弹的话术
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务