原文地址 点击打开链接
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3400
题目大意:在平面上有两条直线:AB,CD,从A到D,如果在直线AB上行驶有速度P,在直线CD上行驶有速度Q,其它地方有速度R,求A到D的最短花费时间。
解题思路:
首先固定AB上一点,第一次我们设把这点设为mid1=B,然后三分去CD上找一点mid2,使A到D花的时间最少。然后固定CD上的mid2,用三分法去AB上找一点mid1,使A->mid1->mid2->D,花费时间最少,重复上述过程。
代码:
- #include<iostream>
- #include<cmath>
- using namespace std;
- const double eps=1e-8;
- struct point
- {
- double x;
- double y;
- };
- point A,B,C,D;
- double P,Q,R;
- point Mid(point l, point r)
- {
- point mid;
- mid.x=(l.x+r.x)/2.0;
- mid.y=(l.y+r.y)/2.0;
- return mid;
- }
- double detance(point a,point b)
- {
- return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
- }
- double stime(point a,point b,point c,point d)
- {
- return detance(a,b)/P+detance(b,c)/R+detance(c,d)/Q;
- }
- double sanfen1(point a, point b, point c, point d,point &mid)
- {
- double rest1,rest2;
- point l,r,mid1,mid2;
- l=c;
- r=d;
- do
- {
- mid1=Mid(l,r);
- mid2=Mid(mid1,r);
- rest1=stime(a,b,mid1,d);
- rest2=stime(a,b,mid2,d);
- if(rest1>rest2)l=mid1;
- else r=mid2;
- }while(fabs(rest1-rest2)>eps);
- mid=mid1;
- return rest1;
- }
- double sanfen2(point d, point c, point b, point a,point &mid)
- {
- double rest1,rest2;
- point l,r,mid1,mid2;
- l=a;
- r=b;
- do
- {
- mid1=Mid(l,r);
- mid2=Mid(mid1,r);
- rest1=stime(a,mid1,c,d);
- rest2=stime(a,mid2,c,d);
- if(rest1>rest2)l=mid1;
- else r=mid2;
- }while(fabs(rest1-rest2)>eps);
- mid=mid1;
- return rest1;
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y);
- scanf("%lf%lf%lf%lf",&C.x,&C.y,&D.x,&D.y);
- scanf("%lf%lf%lf",&P,&Q,&R);
- double t1,t2;
- point mid1,mid2;
- mid1.x=B.x;
- mid1.y=B.y;
- do
- {
- t1=sanfen1(A,mid1,C,D,mid2);
- t2=sanfen2(D,mid2,B,A,mid1);
- }while(fabs(t1-t2)>eps);
- printf("%0.2lf/n",t1);
- }
- return 0;
- }