BZOJ P1857:[Scoi2010]传送带

本文介绍了一种利用三分法解决特定场景下两点间最短行走时间的问题。通过在线段AB和CD上选取合适的点,并结合给定的速度参数,利用二次函数特性找到最优解。文章提供了详细的算法实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Orz,原来是三分大法,还以为有公式,但是推不出来

据说耗费时间是一个二次函数

设在线段AB上取点(x1,y1),CD上取点(x2,y2);

点A坐标为(ax,ay),点D坐标为(dx,dy)

那么时间就是sqrt((ax-x1)^2+(ay-y1)^2)/p同理,可以发现是二次函数

然后三分在AB上的点,和在CD上的点求出答案即可

下面是代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const double eps=1e-3;
int ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
double ans;
double dis(double x,double y,double x1,double y1){
  	double v1=sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
  	return v1;
}
double work(double sx,double sy,double x,double y){
  	double res=dis(ax,ay,sx,sy)/p+dis(sx,sy,x,y)/r+dis(x,y,dx,dy)/q;
  	return res;
}
double calc(double sx,double sy){
  	double lx=cx,ly=cy,rx=dx,ry=dy;
  	while(fabs(lx-rx)>eps||fabs(ly-ry)>eps){
   		double x1=lx+(rx-lx)/3;
		double y1=ly+(ry-ly)/3;
    	double x2=lx+(rx-lx)/3*2;
		double y2=ly+(ry-ly)/3*2;
    	if(work(sx,sy,x1,y1)>work(sx,sy,x2,y2)){
    	  lx=x1;ly=y1;
    	}else{
    	  rx=x2;ry=y2;
    	}
  	}
  	return work(sx,sy,lx,ly);
}
int main(){
	cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>p>>q>>r;
  	double lx=ax,ly=ay,rx=bx,ry=by;
  	while(fabs(lx-rx)>eps||fabs(ly-ry)>eps){
   	 	double x1=lx+(rx-lx)/3;
		double y1=ly+(ry-ly)/3;
    	double x2=lx+(rx-lx)/3*2;
		double y2=ly+(ry-ly)/3*2;
 	   	if(calc(x1,y1)>calc(x2,y2)){
    	  	lx=x1;
			ly=y1;
   		}else{
      		rx=x2;
			ry=y2;
    	}
  	}
  	ans=min(calc(lx,ly),calc(rx,ry));
  	printf("%.2lf\n",ans);
  	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值