您的位置:首页 > 其它

BZOJ1857 SCOI2010 传送带 三分套三分

2017-12-06 11:35 211 查看

大家都很强, 可与之共勉 。

题意:

  给您两条线段,分别为AB,CD(给出A,B,C,D的坐标),您要从A走到D,给出在线段AB的移动速度P,线段CD的移动速度Q,以及线段外的移动速度R,求最短时间。

题解:

  当在AB上固定一点时,我们会发现在另一条线段的点的位置与花费的时间是一个单峰函数,在BD上同理,于是我们可以三分。由物理模型构建出三分,或者呃,打表发现是三分的。

坑点:

  这道题可能有线段是一个点,所以三分写成是dowhile最好。

/**************************************************************
Problem: 1857
User: Lazer2001
Language: C++
Result: Accepted
Time:32 ms
Memory:1292 kb
****************************************************************/

# include <bits/stdc++.h>

const double eps = 1e-8 ;

struct Point  {
double x, y ;
Point ( )  {    }
Point ( double x, double y ) : x ( x ), y ( y )  {  }
inline Point operator + ( const Point& rhs )  const  {
return Point ( x + rhs.x, y + rhs.y ) ;
}
inline Point operator - ( const Point& rhs )  const  {
return Point ( x - rhs.x, y - rhs.y ) ;
}
inline Point operator / ( const double& k )  const  {
return Point ( x / k, y / k ) ;
}
inline double operator * ( const Point& rhs )  const  {
return x * rhs.x + y * rhs.y ;
}
} p [5] ;

inline double dis ( const Point& a, const Point& b )  {
return sqrt ( ( a - b ) * ( a - b ) ) ;
}

double v1, v2, v3 ;

inline double TriDivid ( const Point& cur )  {
Point l = p [2], r = p [3] ;
Point l2, r2, mid ;
double ans = 1e16 ;
do  {
mid = ( r - l ) / 3 ;
l2 = l + mid, r2 = r - mid ;
double rt1 = dis ( p [0], cur ) / v1 + dis ( cur, l2 ) / v3 + dis ( l2, p [3] ) / v2 ;
double rt2 = dis ( p [0], cur ) / v1 + dis ( cur, r2 ) / v3 + dis ( r2, p [3] ) / v2 ;
( rt1 < rt2 ) ? r = r2 : l = l2 ;
ans = std :: min ( rt1, rt2 ) ;
}  while ( dis ( l, r ) > eps ) ;
return ans ;
}

int main ( )  {
for ( int i = 0 ; i < 4 ; ++ i )  {
static double x, y ;
scanf ( "%lf%lf", & x, & y ) ;
p [i] = Point ( x, y ) ;
}

scanf ( "%lf%lf%lf", & v1, & v2, & v3 ) ;

Point l = p [0], r = p [1] ;

double ans = 1e16 ;

do  {
Point l2, r2, mid ;
mid = ( r - l ) / 3 ;
l2 = l + mid, r2 = r - mid ;
double ans1 = TriDivid ( l2 ) ;
double ans2 = TriDivid ( r2 ) ;
( ans1 < ans2 ) ? r = r2 : l = l2 ;
ans = std :: min ( ans1, ans2 ) ;
}   while ( dis ( l, r ) > eps ) ;

return printf ( "%.2lf\n", ans ), 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: