1. 程式人生 > >Scoi2010——傳送帶(三分套三分=九分)

Scoi2010——傳送帶(三分套三分=九分)

描述

在一個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

因為有兩個斷點需要列舉

所以單純的三分是沒法做到

考慮到如果我們已經固定了一個斷點

那就可以三分求出另一個斷點的最優值

那我們可以對這個斷點三分

然後對於每個三分的值再三分一次

然後......就是九分了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const double eps=1e-4;
inline int read(){
	char ch=getchar();
	int res=0;
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
	return res;
}
double ax,ay,bx,by,cx,cy,dx,dy,p,q,r;
inline double dis(double x1,double x2,double y1,double y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
inline double calc(double x1,double x2,double y1,double y2){
	return dis(ax,x1,ay,y1)/p+dis(x1,x2,y1,y2)/r+dis(x2,dx,y2,dy)/q;
}
inline double solve(double x,double y){
	double lx=cx,ly=cy,rx=dx,ry=dy;
	while(fabs(lx-rx)>=eps||fabs(ly-ry)>=eps){
		double x1=lx+(rx-lx)/3,x2=lx+(rx-lx)*2/3,y1=ly+(ry-ly)/3,y2=ly+(ry-ly)*2/3;
		if(calc(x,x1,y,y1)>calc(x,x2,y,y2))lx=x1,ly=y1;
		else rx=x2,ry=y2;
	}
	return calc(x,lx,y,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,x2=lx+(rx-lx)*2/3,y1=ly+(ry-ly)/3,y2=ly+(ry-ly)*2/3;
		if(solve(x1,y1)<solve(x2,y2))rx=x2,ry=y2;
		else lx=x1,ly=y1;
	}
	printf("%.2lf",solve(lx,ly));
}