小D的家A和学校B都恰好在以点F为焦点的双曲线上,而小D每日所需的生活水源在一条平行该双曲线准线的直线上,设它的值为v。大家都知道,每天都是要喝水的,但是小D有点懒,他希望自己能在去上学或者回家的时候顺路打桶水,并且走最短的路,你能帮助他吗?下图所示样例的情况,已知焦点在x轴上,那么其准线垂直x轴,即x=v,故可作出河流所在直线如图,那么最优路线为从家A到点C(0,5.8888889)取水,然后再到学校B,那么总长度就是这两段各自距离之和,即|AC| + |CB|。
输入
第一行输入数据组数T(T <= 100)。每组数据包括四个坐标,其格式如下:第一行输入点A的坐标X1,Y1第二行输入点B的坐标X2,Y2第三行输入点F的坐标X3,Y3第四行输入值v保证双曲线焦点在坐标轴上,保证A,B点的坐标以及v值均为整数且绝对值不大于1000,保证F坐标值不超过1000.0。 相邻两组数据之间有一空行。输出
输出
输入
第一行输入数据组数T(T <= 100)。每组数据包括四个坐标,其格式如下:第一行输入点A的坐标X1,Y1第二行输入点B的坐标X2,Y2第三行输入点F的坐标X3,Y3第四行输入值v保证双曲线焦点在坐标轴上,保证A,B点的坐标以及v值均为整数且绝对值不大于1000,保证F坐标值不超过1000.0。 相邻两组数据之间有一空行。输出
输出
Case #x: s,x表示数据组数,s表示该最短路的距离,保留6位小数样例
输入
2
40 40
-920 480
0.000000 73.9889111581
636
5 7
4 5
4.9286577 0
0
40 40
-920 480
0.000000 73.9889111581
636
5 7
4 5
4.9286577 0
0
样例输出
Case #1: 1219.468737
Case #2: 9.219544
思路:2个点到一条线求最短的距离
和双曲线没有太大的关系,焦点就是为了判断准线是平行于x轴还是y轴,如果是y轴的话,把所有点的x轴 y轴坐标交换。然后分情况讨论
1)对称轴在2点之间
2)2点在对称轴的一侧
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
int icase;
scanf("%d",&icase);
for(int t=1;t<=icase;t++)
{
double xa,ya,xb,yb,fa,fb,v,sum;
scanf("%lf%lf",&xa,&ya);
scanf("%lf%lf",&xb,&yb);
scanf("%lf%lf",&fa,&fb);
scanf("%lf",&v);
if(fb!=0)
{
swap(ya,xa);
swap(yb,xb);
}
if(xa<xb)
{
swap(xa,xb);
swap(ya,yb);
}
double x,y;
if(xb<v&&v<xa)
{
x=xa-xb;
y=fabs(ya-yb);
}
else
{
x=xa+xb-2*v;
y=fabs(ya-yb);
}
sum=sqrt(x*x+y*y);
printf("Case #%d: %.6lf\n",t,sum);
}
return 0;
}