NBUT 1462 台球碰撞 几何基础 思维

  • [1462] 台球碰撞

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 在平面直角坐标系下,台球桌是一个左下角在(0,0),右上角在(L,W)的矩形。有一个球心在(x,y),半径为R的圆形母球放在台球桌上(整个球都在台球桌内)。受撞击后,球沿极角为a的射线(即:x正半轴逆时针旋转到此射线的角度为a)飞出,每次碰到球桌时均发生完全弹性碰撞(球的速率不变,反射角等于入射角)。




    如果球的速率为vs个时间单位之后球心在什么地方?

  • 输入
  • 输入文件最多包含25组测试数据,每个数据仅一行,包含8个正整数L,W,x,y,R,a,v,s(100<=L,W<=105, 1<=R<=5, R<=x<=L-R, R<=y<=W-R, 0<=a<360, 1<=v,s<=105),含义见题目描述。L=W=x=y=R=a=v=s=0表示输入结束,你的程序不应当处理这一行。
  • 输出
  • 对于每组数据,输出仅一行,包含两个实数x, y,表明球心坐标为(x,y)。x和y应四舍五入保留两位小数。
  • 样例输入
  • 100 100 80 10 5 90 2 23
  • 110 100 70 10 5 180 1 9999
  • 0 0 0 0 0 0 0 0
  • 样例输出
  • 80.00 56.00
  • 71.00 10.00
  • 提示
  • 来源
  • 湖南省第六届大学生计算机程序设计竞赛
点击打开题目链接

我们把速度分解成横纵两个方向的分量

然后先求出横坐标最终长度 再用最终长度mod L-2R

台球实际上是在 L-2R W-2R的范围内移动的

代码

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double PI = 4 * atan(1.0);    //注意π的定义

int main()
{
    int L, W, x, y, R, a, v, s;
    while (~scanf("%d%d%d%d%d%d%d%d", &L, &W, &x, &y, &R, &a, &v, &s))
    {
        if (L == 0) break;
        double xOfAns, yOfAns, vx, vy; //最终坐标,速度分量

        L -= 2 * R;     //将球转换成一个点
        W -= 2 * R;
        x -= R;
        y -= R;

        vx = v * cos(a / 180.0 * PI);   //速度分量 注意角度转弧度
        vy = v * sin(a / 180.0 * PI);

        int nx = (x + vx * s) / L;
        int ny = (y + vy * s) / W;

        xOfAns = x + s * vx - nx * L - (nx % 2) * L;//当nx为奇数时坐标是len-x;这里x-len同样道理
        yOfAns = y + s * vy - ny * W - (ny % 2) * W;

        if (xOfAns < 0) xOfAns = -xOfAns;
        if (yOfAns < 0) yOfAns = -yOfAns;
        xOfAns += R;
        yOfAns += R;

        printf("%.2lf %.2lf\n", xOfAns, yOfAns);
    }
    return 0;
}

下面是标程,方法大致相同:

#include<stdio.h>
#include<math.h>
int main()
{
    double L, W, x, y, R, a, v, s;
    while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &L, &W, &x, &y, &R, &a, &v, &s) == 8)
    {
        if(!L) break;
        x -= R;
        y -= R;
        L -= R*2;
        W -= R*2;
        a *= acos(0.0)/90.0;
        double dx = fmod(fmod(v*s*cos(a), L*2)+L*2, L*2);
        double dy = fmod(fmod(v*s*sin(a), W*2)+W*2, W*2);
        if(x+dx <= L) x += dx;
        else if(x+dx <= L*2) x = L-(x+dx-L);
        else x = x+dx-L*2;
        if(y+dy <= W) y += dy;
        else if(y+dy <= W*2) y = W-(y+dy-W);
        else y = y+dy-W*2;
        printf("%.2lf %.2lf\n", x+R, y+R);
    }
    return 0;
}


你可能感兴趣的:(ACM,几何)