ACM 2013 长沙区域赛 Collision (几何)

ZOJ - 3728  

题目大意:

       一个奖牌放在原点,奖牌外面有一个圈,一个硬币在光滑平面上移动,如果撞到奖牌就会反弹。求硬币在圈内的总时间。

       注意反弹就是原路返回,reflect......

这场区域赛的题干一直让人很不舒服,不知道是出题人的锅还是我自己的锅......

题解:

      ①硬币圆心的运动轨迹  (x+v_{x}t,y+v_{y}t), 计算它与原点的距离,(x+v_{x}t)^{2}+(y+v_{y}t)^{2}=(R+r)^{2} 是一元二次方程,如果\Delta =b^{2}-4ac>0,说明硬币会和大圆有相交,求出的两个解之差t2-t1就是硬币在大圆内的时间。

     ②计算(x+v_{x}t)^{2}+(y+v_{y}t)^{2}=(R_{m}+r)^{2},如果\Delta =b^{2}-4ac\leq 0,说明硬币不会和奖牌有碰撞,答案就是t2-t1。如果\Delta =b^{2}-4ac>0,求出两个解为tt1,tt2,答案就是(t2-t1)-(tt2-tt1)。

 

有2个WA点:

①给出的速度方向可能正好和奖牌在的方向反向,这时永远不会相交,求出来的t1,t2就会有负的,此时要判断一下。

②读Rm,R,r,x,ym,vx,vy时,不能用int读,后面的4*(x*vx+y*vy)*(x*vx+y*vy)会爆int的,用double读。

#include<bits/stdc++.h>
#include<cstring>
using namespace std;
#define ll long long
int main()
{
    double Rm,R,r,x,y,vx,vy;
    double ans;
    cout<<fixed<<setprecision(4);
    while(cin>>Rm>>R>>r>>x>>y>>vx>>vy)
    {
        double del=4*(x*vx+y*vy)*(x*vx+y*vy)-4*(vx*vx+vy*vy)*(x*x+y*y-R*R-2*R*r-r*r);
        if(del<=0.0)
        {
            cout<<0.0<<endl;
            continue;
        }
        double t1=(-2*(x*vx+y*vy)-sqrt(del))/2*(vx*vx+vy*vy);
        double t2=(-2*(x*vx+y*vy)+sqrt(del))/2*(vx*vx+vy*vy);
        if(t1<0.0 || t2<0.0)
        {
            cout<<0.0<<endl;
            continue;
        }
        double del1=4*(x*vx+y*vy)*(x*vx+y*vy)-4*(vx*vx+vy*vy)*(x*x+y*y-Rm*Rm-2*Rm*r-r*r);
        if(del1<=0.0)
            ans=sqrt(del)/(vx*vx+vy*vy);
        else
            ans=(sqrt(del)-sqrt(del1))/(vx*vx+vy*vy);
        cout<<ans<<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值