【zzuliOJ】1909 - 小火山的友情距离(数学)

来源:互联网 发布:sql server和mysql区别 编辑:程序博客网 时间:2024/05/17 09:44

点击打开题目

1909: 小火山的友情距离

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 16  Solved: 5

SubmitStatusWeb Board

Description

小火山和他的朋友岩浆, 分别打算去买商店买一些东西。小火山的起始位置为(X1, Y1),终止位置为(X2, Y2), 速度为U;
岩浆的起始位置为(X3, Y3), 终止位置为(X4, Y4), 速度为V, 双方一块出发, 到达终止位置后, 都会在终止位置停留。 现在小火山想知道他和岩浆在此过程中的最小距离。

Input

输入第一行是一个整数T(T <= 100), 表示一共有T组数据。
对于每组数据都有十个数字X1, Y1,X2, Y2, U, X3, Y3, X4, Y4, V。 分别代表小火山和岩浆的起始位置, 终止位置和速度。
(|X1, Y1,X2, Y2, X3, Y3, X4, Y4| <= 1000000, 1 <= U, V <= 1000000)

Output

对于每组数据输出一个数字, 表示此过程中的最小距离, 最后结果保留四位小数。

Sample Input

2
1 0 2 2 5 0 0 -1 -1 4
0 0 2 0 3 1 1 2 1 2

Sample Output

1.00001.0000

HINT

Source

zzuli



首先应该分情况,看谁先到终点。

然后分别求出两个点的运动坐标的参数方程,然后列出dis的表达式,可以看出是关于时间t的一元二次函数,找出对称轴找最小值就行了。


代码如下:

#include <stdio.h>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define CLR(a,b) memset(a,b,sizeof(a))#define INF 0x3f3f3f3f#define LL long long#define PI acos(-1)double dis(double x1,double y1,double x2,double y2){    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));}int main(){    int u;    scanf ("%d",&u);    double x1,x2,x3,x4,y1,y2,y3,y4,v1,v2;    double t1,t2,t;    double k1,k2;    double l1,l2;    double vx1,vy1,vx2,vy2;    double ans,ans1,ans2;    double c1,c2,c3;    while (u--)    {        scanf ("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&v1,&x3,&y3,&x4,&y4,&v2);        l1 = dis(x1,y1,x2,y2);        l2 = dis(x3,y3,x4,y4);        t1 = l1 / v1;        t2 = l2 / v2;        vx1 = v1 * (x2-x1) / l1;        vy1 = v1 * (y2-y1) / l1;        vx2 = v2 * (x4-x3) / l2;        vy2 = v2 * (y4-y3) / l2;        t = min (t1 , t2);        c1 = pow(vx1-vx2 , 2) + pow(vy1-vy2 , 2);        c2 = 2 * ((x1-x3) * (vx1-vx2) + (y1-y3) * (vy1-vy2));        c3 = pow(x1-x3 , 2) + pow(y1-y3 , 2);        if (c2 >= 0)            ans1 = c3;        else        {            double nice = - c2 / (2 * c1);      //二次函数            if (nice <= t)                ans1 = c1 * nice * nice + c2 * nice + c3;            else                ans1 = c1 * t * t + c2 * t + c3;        }        if (t1 == t2)            ans2 = ans1;        else if (t1 < t2)        {            t = t2 - t1;            x3 = x3 + vx2 * t1;            y3 = y3 + vy2 * t1;            c1 = vx2 * vx2 + vy2 * vy2;            c2 = 2 * (vx2 * (x3-x2) + vy2 * (y3-y2));            c3 = pow(x3-x2 , 2) + pow(y3-y2 , 2);            if (c2 >= 0)                ans2 = c3;            else            {                double nice = - c2 / (2 * c1);      //二次函数                if (nice <= t)                    ans2 = c1 * nice * nice + c2 * nice + c3;                else                    ans2 = c1 * t * t + c2 * t + c3;            }        }        else        {            t = t1 - t2;            x1 = x1 + vx1 * t2;            y1 = y1 + vy1 * t2;            c1 = vx1 * vx1 + vy1 * vy1;            c2 = 2 * (vx1 * (x1-x4) + vy1 * (y1-y4));            c3 = pow(x1-x4 , 2) + pow(y1-y4 , 2);            if (c2 >= 0)                ans2 = c3;            else            {                double nice = - c2 / (2 * c1);      //二次函数                if (nice <= t)                    ans2 = c1 * nice * nice + c2 * nice + c3;                else                    ans2 = c1 * t * t + c2 * t + c3;            }        }        ans = sqrt(min(ans1 , ans2));        printf ("%.4lf\n",ans);    }    return 0;}


0 0
原创粉丝点击