【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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章