题目 1075: 台球碰撞

 

样例输入

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

思路(参考BornFated的思路)(【BornFated】1075_台球碰撞_C语言题解-Dotcpp编程社区):

A.本题的主要问题在于建模而不是编程,涉及到二维平面内的受边界限制斜向运动

 由于球在碰撞时,被碰的是球表面,所以我们考虑重新建立坐标系,具体如下

 

如图,矩形的两边边长都缩短了2R,此时我们便可以把球体抽象成一个质点。

B.由于球体做斜向运动,我们考虑将其运动进行分解,分开处理

先处理X轴,如图

由于题目中的起始坐标x不一定在原点上,所以我们可以把它看成从原点出发移动x个单位的运动,由于初速度方向不定,从原点出发, 无论是向左运动还是向右运动,它都会变成向右运动(向左瞬间碰壁反弹)举个例子:假设质点从 3 开始发生-27的位移,也就相当于是从原点开始发生了(-27+3)=(-24)的位移,也就相当于从原点开始发生了24的总位移,

值得注意的是,一旦总位移大于两倍的边长,它的实际位移就应该减去一个两倍边长,实际上,边界范围的两倍是一个周期。

综上所述:假设初始坐标为 x ,移动位移为 s ,边界长度为 L ,那么求解最终坐标的方法就是:先求出转化后的从原点出发的总位移 Dx,Dx=fabs(x+s),之后若 Dx 大于 2L 则 Dx-=2L 直到 Dx小于2L,最后若 Dx小于L 则 Dx 即最终坐标,若 Dx介于2L和L之间 ,那么最终坐标为 2L-Dx 。

最后把该思路推广到y轴上,便可以得出结论

代码如下:

 

#include<stdio.h>
#include<math.h>
void ZB(double L, double W, double x, double y, double R, double a, double v, double s, double Dx, double Dy);
int main()
{
	double L[26], W[26], x[26], y[26], R[26], a[26], v[26], s[26];
	double Dx = 0, Dy = 0;
	int i,j=0;
	for ( i = 0; i < 26; i++)
	{
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &L[i], &W[i], &x[i], &y[i], &R[i], &a[i], &v[i], &s[i]);
		if (L[i] == 0 && W[i] == 0 && x[i] == 0 && y[i] == 0 && R[i] == 0 && a[i] == 0 && v[i] == 0 && s[i] == 0)
		{
			j = i;
			break;
		}
	}
	for ( i = 0; i < j; i++)
	{
		ZB(L[i], W[i], x[i], y[i], R[i], a[i], v[i], s[i],Dx,Dy);
	}
	return 0;
}
void ZB(double L, double W, double x, double y, double R, double a, double v, double s,double Dx,double Dy)
{
	double l, w, x0, y0;
	a = a / 180.0 * acos(-1);
	l = L - 2 * R;
	w = W - 2 * R;
	x0 = x - R;
	y0 = y - R;
	Dx = fabs(v * s * cos(a) + x0);
	Dy = fabs(v * s * sin(a) + y0);
	while (Dx > 2 * l)
	{
			Dx -= 2 * l;
	}
	while (Dy > 2 * w)
	{
		Dy -= 2 * w;
	}
	if (Dx > l && Dx < 2 * l) Dx = 2 * l - Dx;
	else;
	if (Dy > w && Dy < 2 * w) Dy = 2 * w - Dy;
	else;
	printf("%.2lf %.2lf\n", Dx + R, Dy + R);
	
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小梁今天卷没卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值