2013长沙区域赛——C.Collision(ZOJ 3728)

传送门

There's a round medal fixed on an ideal smooth table, Fancy is trying to throw some coins and make them slip towards the medal to collide. There's also a round range which shares exact the same center as the round medal, and radius of the medal is strictly less than radius of the round range. Since that the round medal is fixed and the coin is a piece of solid metal, we can assume that energy of the coin will not lose, the coin will collide and then moving as reflect.

Now assume that the center of the round medal and the round range is origin ( Namely (0, 0) ) and the coin's initial position is strictly outside the round range. Given radius of the medal Rm, radius of coin r, radius of the round range R, initial position (x, y) and initial speed vector (vx, vy) of the coin, please calculate the total time that any part of the coin is inside the round range.

Please note that the coin might not even touch the medal or slip through the round range.

Input

There will be several test cases. Each test case contains 7 integers Rm, R, r, x, y, vx and vy in one line. Here 1 ≤ Rm < R ≤ 2000, 1 ≤ r ≤ 1000, R + r < |(x, y)| ≤ 20000, 1 ≤ |(vx, vy)| ≤ 100.

Output

For each test case, please calculate the total time that any part of the coin is inside the round range. Please output the time in one line, an absolute error not more than 1e-3 is acceptable.

Sample Input

5 20 1 0 100 0 -1
5 20 1 30 15 -1 0

Sample Output

30.000
29.394

题意:

给定的两个同心圆,他们的的圆心都是原点(0,0),现在给一枚硬币,还有这枚硬币移动的向量表示,现在让求硬币在圆上运动的时间(这个硬币撞到里面的圆的时候会反弹)

题解:

暂且定半径为Rm的圆为1,半径为R的圆为2,现在要计算硬币在圆里面运动的时间长度

在刚开始做的时候采用的是求硬币运动方程的方法来做的,这个时候考虑的是三种情况

1、运动轨迹跟2无交点(外离)

2、运动轨迹跟2有交点但是跟1没有交点

3.运动轨迹跟1有交点

不过这里要注意的一点就是,什么时候才能算是有交点:


 

在两个圆相切的时候他们就应该开始计算了!

不过,这道题让算的是时间

既然是让算时间,那么我们就采用参数方程来表示硬币的圆心所在的位置

{   x=x+vx*t;

{   y=y+vy*t;

给出了一个点,我们现在结合刚才说的通过轨迹方程的做法,把一维的图形转换成点到点的模型来处理

硬币圆心到原点的距离可以类比为原点到轨迹方程的距离,这样问题就又被分为三部分了

计算△,通过△判断与圆的关系

计算时间t,如果说时间t是负数,那么就说明现在的移动方向是反方向的,也就是说,硬币是不会往圆上走的,这里很重要,因为用第一种方法做的时候少考虑了这么一种情况WA了很多次。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;
double a,b,c,o,t1,t2,t3;
int main()
{
    double Rm,R,r,x,y,vx,vy;
    while(~scanf("%lf %lf %lf %lf %lf %lf %lf",&Rm,&R,&r,&x,&y,&vx,&vy))
    {
        a=vx*vx+vy*vy;
        b=2*(x*vx+y*vy);
        c=x*x+y*y-(R+r)*(R+r);//现在判断跟外圆的交点
        o=b*b-4*a*c;
        if(o<=0)
        {
            printf("0.000\n");
        }
        else
        {
            //现在代表的是有交点
            t1=(b*(-1)-sqrt(o))/(2*a);
            if(t1<=0)
            {
                printf("0.000\n");
            }
            else
            {
                //现在判断跟里面的有没有交点
                t2=(((-1)*b)+sqrt(o))/(2*a);
                //现在判断跟Rm有没有交点,如果没有的话
                c=x*x+y*y-(Rm+r)*(Rm+r);
                o=b*b-4*a*c;
                if(o<=0)
                {
                    printf("%.3lf\n",t2-t1);
                }
                else
                {
                    t3=((-b)-sqrt(o))/(2*a);
                    printf("%.3lf\n",2*(t3-t1));
                }
            }
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值