HDU 4793 Collision (解二元一次方程) -2013 ICPC长沙赛区现场赛

题目链接

题目大意 :有一个圆硬币半径为r,初始位置为x,y,速度矢量为vx,vy,有一个圆形区域(圆心在原点)半径为R,还有一个圆盘(圆心在原点)半径为Rm (Rm < R),圆盘固定不动,硬币撞到圆盘上会被反弹,不考虑能量损失,求硬币在圆形区域内运动的时间。 

运动方程:

x'=x+t*vx;

y'=y+t*vy;

r'=r1+r2;

x'^2+y'^2=r'^2;

难点在于如何构造出两个运动轨迹方程,为什么这么构造。

一共四种情况:

第一种:与外圆相离相切,输出0。

第二种:与外圆相交,与内圆相离相切,输出外圆两个解的差的绝对值。

第三种:与外圆相交,与内圆相交,输出外圆两个解的差的绝对值减去内圆两个解的差的绝对值。

第四种:与外圆相交即有两个解,但是两个解都是负的(要么都是负数要么都是正数),也就是说反向运动才能进入大圆,输出0。

 

#include <bits/stdc++.h>
const double eps=0.00000001;
using namespace std;
int main()
{
    double Rm,R,r,x,y,vx,vy,k,b,flag;
    while(scanf("%lf%lf%lf%lf%lf%lf%lf",&Rm,&R,&r,&x,&y,&vx,&vy)!=EOF)
    {
        double a1=vx*vx+vy*vy;
        double b1=2*x*vx+2*y*vy;
        double c1=x*x+y*y-(R+r)*(R+r);
        double a2=vx*vx+vy*vy;
        double b2=2*x*vx+2*y*vy;
        double c2=x*x+y*y-(Rm+r)*(Rm+r);
        double d1=b1*b1-4.0*a1*c1;
        double d2=b2*b2-4.0*a2*c2;
        double ansbig1=(-b1-sqrt(d1))/(2.0*a1);
        double ansbig2=(-b1+sqrt(d1))/(2.0*a1);
        double anssma1=(-b2-sqrt(d2))/(2.0*a2);
        double anssma2=(-b2+sqrt(d2))/(2.0*a2);
        if(d1<=eps) //与大圆相离
        {
            puts("0.000");
        }
        else if(ansbig2>=eps)//进入大圆
        {

            if(d2<=eps) //最好的情况
            {
                double ans=fabs(ansbig1-ansbig2);
                printf("%.3f\n",ans);
            }
            else
            {
                double ans=fabs(ansbig1-ansbig2)-fabs(anssma1-anssma2);
                printf("%.3f\n",ans);
            }
        }
        else //反向 进入时间为负
        puts("0.000");
    }
    return 0;
}

 

posted @ 2016-09-22 21:24  Ritchie丶  阅读(320)  评论(0编辑  收藏  举报