【C++】「一本通 1.2 练习 4」「SCOI-2010」传送带

【来源】

SCOI-2010
一本通题库-1439
LibreOJ-10017
BZOJ-1857
vjudge

【题目描述】

在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间

【输入格式】

输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R

【输出格式】

输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位。

【样例输入】

0 0 0 100
100 0 100 100
2 2 1

【样例输出】

136.60

【数据范围】

对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000。
1<=P,Q,R<=10。

【解析】

三分套三分。

考虑将其中一个点固定,那么对于另一个点用三分可求出这个点的位置。
该点有最小值,它的左右两点都比他大,所以是单峰函数。
那么对于最开始的点,我们同样也是单峰函数,也可以三分。

【代码】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))
#define sqr(a)             (a)*(a)

using namespace std;

typedef long long LL;

const int N=105;
const int inf=1e9;
const double eps=1e-12;

double xa,ya,xb,yb,xc,yc,xd,yd,p,q,r;

inline double calc(double x1,double y1,double x2,double y2) {
    
    
    return sqrt(sqr(x1-x2)+sqr(y1-y2));
}

double check(double x,double y) {
    
    
	double xl=xc,yl=yc,xr=xd,yr=yd;
	while(fabs(xr-xl)>eps || fabs(yr-yl)>eps) {
    
    
		double xmid1=xl+(xr-xl)/3;
		double ymid1=yl+(yr-yl)/3;
		double xmid2=xr-(xr-xl)/3;
		double ymid2=yr-(yr-yl)/3;
		double ans1=calc(xa,ya,x,y)/p+calc(x,y,xmid1,ymid1)/r+calc(xmid1,ymid1,xd,yd)/q;
		double ans2=calc(xa,ya,x,y)/p+calc(x,y,xmid2,ymid2)/r+calc(xmid2,ymid2,xd,yd)/q;
		if(ans1<ans2) xr=xmid2,yr=ymid2;
			else xl=xmid1,yl=ymid1;
    }
	double ret=calc(xa,ya,x,y)/p+calc(x,y,xl,yl)/r+calc(xl,yl,xd,yd)/q;
	return ret;
}

int main() {
    
    
	scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
	scanf("%lf%lf%lf%lf",&xc,&yc,&xd,&yd);
	scanf("%lf%lf%lf",&p,&q,&r);
	double xl=xa,yl=ya,xr=xb,yr=yb;
    while(fabs(xr-xl)>eps || fabs(yr-yl)>eps) {
    
    
		double xmid1=xl+(xr-xl)/3;
		double ymid1=yl+(yr-yl)/3;
        double xmid2=xr-(xr-xl)/3;
		double ymid2=yr-(yr-yl)/3;
        if(check(xmid1,ymid1)<check(xmid2,ymid2)) xr=xmid2,yr=ymid2;
        	else xl=xmid1,yl=ymid1;
    }
    printf("%0.2lf\n",check(xl,yl));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ljnoit/article/details/105875891