码迷,mamicode.com
首页 > 其他好文 > 详细

计算几何--bnu51638

时间:2016-04-29 19:55:11      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:

Air Hockey

Time Limit: 1000ms
Memory Limit: 262144KB
64-bit integer IO format: %lld      Java class name: Main
Special Judge
Type:   

无聊的过河船同学和无聊的胀鱼同学非常喜欢打桌上冰球(其实只是喜欢听球碰撞时的声音)。在无聊的一天,无聊的过河船同学想到了一个无聊的玩法:两人同时将两个球放桌面上,同时击出,然后听两颗球撞在一起时的声音。然而他们都对击球的精确度把握得不是很好,所以这两颗球并不一定能相撞。

现在假设桌面无限大,并且绝对光滑,给出两球的初始位置、半径和运动速度,保证两球初始没有接触。无聊的过河船同学想知道两球能否相撞(接触即认为相撞),如果能,他想知道两球相撞的时间(从两人击球时开始计时),如果不能,他想知道全过程中两球距离的最小值,这里两球距离的定义为两球上任取两个点的距离的最小值,数据保证这种情况下答案不小于技术分享。请注意,冰球是个圆柱体,从空中往下看就是一个圆,且在这个问题中,冰球的高度可以忽略不计。

Input

第一行是一个正整数技术分享,表示测试数据的组数,

每组测试数据包含两行,

技术分享行包含五个绝对值不大于技术分享的整数技术分享,表示第技术分享个球的初始位置、半径和运动速度。

Output

对于每组测试数据,若两球能相撞,输出两球相撞的时间,否则输出全过程中两球距离的最小值,相对误差不超过技术分享即可,

也就是说,令输出结果为技术分享,标准答案为技术分享,若满足技术分享,则输出结果会被认为是正确答案。

Sample Input

2
0 0 2 1 0
11 0 1 -1 0
0 0 2 1 0
11 5 1 -1 0

Sample Output

4.0000000000
2.0000000000

Hint

对于第一组样例,两球在击球后4.0秒时发生碰撞,

对于第二组样例,两球不发生碰撞,且在击球后5.5秒时两球距离最近,此时距离为2.0。

Source

Author

quailty
解:

设时间为t时两个球相撞或者两个球距离最近,用t可以表示出两个球的坐标 Q1( x1+t*vx1  ,  y1+t*vy1)  Q2(  x2+t*vx2   ,    y2+t*vy2)  ,

Q1Q2的距离=  aqrt{(x1-x2)^2  +(y1-y2)^2   } =r1+r2;     整理方程得到一个关于t 的一元二次方程  sqrt( a t^2  +  b t + c )=  r1+r2;

求解该方程,分a=0和a!=0,a!=0,求解 △<0,△=0,△>0,当△<0时无解,求解方程左边的最小值 ,即 t = -b/(2*a),t>0, 带入方程得 d= sqrt ((4ac-b^2)/(4a) ),ans=d-(r1+r2);   t<0 ,ans=sqrt(c)-(r1+r2) 。 当△>=0时,ans=min(t1,t2)。当a=0,时,ans=sqrt(c)-(r1+r2)。

又复习了一遍初中知识

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
double solve(double a,double b,double c)
{
    double dat=b*b-4.0*a*c;
    if(dat<0)
        return -1;
    double x1= ( -b+sqrt(dat) )/2.0/a;
    double x2= ( -b-sqrt(dat) )/2.0/a;
     if(x2>=0.0)
    return x2;
    if(x2<0&&x1>0)
        return x1;
    if(x1<0&&x2<0)
        return -1;
}
int main()
{
    int t;
    double x1,y1,r1,vx1,vy1;
    double x2,y2,r2,vx2,vy2;
    double x,vx,y,vy;
    double a,b,c;
    double R;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf%lf",&x1,&y1,&r1,&vx1,&vy1);
        scanf("%lf%lf%lf%lf%lf",&x2,&y2,&r2,&vx2,&vy2 );
        x=x1-x2;///c
        y=y1-y2;///c
        vx=vx1-vx2;///a
        vy=vy1-vy2;///a

        a=vx*vx+vy*vy;
        c=x*x+y*y;
        b=2.0*(x*vx+y*vy);
        R=1.0*(r1+r2)*(r1+r2);
        double t=-1.0*b/2.0/a;
        if(a!=0)
        {
            double ans=solve(a,b,c-R);
            if(ans<0&&t<0)
            printf("%.10lf\n",sqrt(c)-r1-r2);

            if(ans<0&&t>=0)
            printf("%.10lf\n",sqrt( (4.0*a*c-b*b) /(4.0*a) )-r1-r2);

            if(ans>=0)
            printf("%.10lf\n",ans);
        }
        else
        printf("%.10lf\n",sqrt(c)-r1-r2);
    }
    return 0;
}


计算几何--bnu51638

标签:

原文地址:http://blog.csdn.net/yuanjunlai141/article/details/51227714

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!