HDU - 6373 Pinball (计算集合 + 物理基础)

There is a slope on the 2D plane. The lowest point of the slope is at the origin. There is a small ball falling down above the slope. Your task is to find how many times the ball has been bounced on the slope.

It’s guarantee that the ball will not reach the slope or ground or Y-axis with a distance of less than 1 from the origin. And the ball is elastic collision without energy loss. Gravity acceleration g=9.8m/s2g=9.8m/s2.

这里写图片描述

Input

There are multiple test cases. The first line of input contains an integer T (1 ≤≤ T ≤≤ 100), indicating the number of test cases.

The first line of each test case contains four integers a, b, x, y (1 ≤≤ a, b, -x, y ≤≤ 100), indicate that the slope will pass through the point(-a, b), the initial position of the ball is (x, y).

Output

Output the answer.

It’s guarantee that the answer will not exceed 50.

Sample Input

1
5 1 -5 3

Sample Output

2


这道题目可以简化成一个小球从从斜坡顶上掉落的问题,我看大家都是硬算,什么小球的斜角啊什么乱七八糟的麻烦的很,这里可以用到我们高中的矢量分解知识,从小球接触斜面的瞬间可以把运动过程沿着垂直斜面方向和斜面方向分解成两个运动过程:1,一个沿着斜面的带初速度的匀加速运动,2,一个垂直斜面加速度恒定的上抛运动。注意这里两个运动都是直线运动,收到的加速度都是由重力分解而成是恒定的力。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const double g = 9.80;
#define EXP 0.000000000000001
double sovel(double a,double b,double c)  //计算带初速的匀加速运动的一元二次方程
{
    double disc = b*b - 4 * a*c;
    if ((disc>-EXP) && (disc < EXP))
    {
        return (-b / (2 * a));
    }
    else if (disc >= EXP)
    {
        disc=sqrt(disc);
        //printf("t1= %lf t2=%lf\n",(-b + disc) / (2 * a), (-b - disc) / (2 * a));
        return max( (-b + disc) / (2 * a), (-b - disc) / (2 * a));
    }
    else
    {
        return -1;
    }
}
int main() {
    double a,b,x,y;
    int T;
    while (cin>>T) {
        while (T--) {
            cin>>a>>b>>x>>y;
            x=-1*x;
            double L=sqrt(a*a+b*b);
            double tan=b/a,sin=b/L,cos=a/L;
            double H=y-tan*x,l=x/cos;
            double v=sqrt(2*g*H),t,t2;
            double v1=cos*v,v2=sin*v,a1=cos*g,a2=sin*g;

            t=sovel(a2/2.0, v2, -1*l);
            t2=(v1/a1)*2;
            //cout<<t<<" "<<t2<<endl;
            double ans=t/t2;
            cout<<(int)ans+1<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/J1nAB1n9/article/details/81668192