题目链接:点击打开链接;
题意:本题给出两条线段,一条线段端点为a,b;另一条线段端点是c,d,在两条线段和不在线段上有不同的速度,求最短时间。
分析:本题一共有三段时间,在a-b上,在c-d上,在空白的地方。设着三段时间是x,y,z。则一旦x和y确定之后,z就能确定,因为这样在两线段上的点就确定了,z也就求出来了,如果x确定时y不确定的话,z和y有关系,所以时间是有一个极值,想到极值,就应该三分求最适合的y。而对于x来说,三分求解x的话可以搞出对应点的y的极值,也就能求出队应的y的极值。这是就解出来了。
代码如下:
#include <math.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; const double eps=1e-7; const double ee=1e-9; struct Point{ double x,y; }; double dis(Point a,Point b){ return sqrt(ee+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double q,p,r; Point a,b,c,d,tmpx,tmpy; double call(double t){ tmpy.x=d.x+(c.x-d.x)/dis(c,d)*t*q; tmpy.y=d.y+(c.y-d.y)/dis(c,d)*t*q; return t+dis(tmpx,tmpy)/r; } double sanfen(double t){ tmpx.x=a.x+(b.x-a.x)/dis(a,b)*t*p; tmpx.y=a.y+(b.y-a.y)/dis(a,b)*t*p; double low,high,mid,midd; low=0; high=dis(c,d)/q; while(high-low>eps){ mid=(low+high)/2; midd=(mid+high)/2; if(call(mid)<call(midd))high=midd; else low=mid; } return t+call(mid); } //三分求y值 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 low,high,mid,midd; low=0; high=dis(a,b)/p; while(high-low>eps){ mid=(low+high)/2; midd=(mid+high)/2; if(sanfen(mid)<sanfen(midd))high=midd; else low=mid; } //三分求x的值 printf("%.2f\n",sanfen(mid)); } return 0; }
时间: 2024-10-29 04:03:19