PATL3-013非常弹的球

本题显然是水题
题目连接:PATL3-013非常弹的球
实际上推出公式真的是水题,甚至模拟算也可。
角度45度时最远(为什么?高中物理王后雄辅导书证明过了,不会真的有人还不知道45度抛最远吧 )。那么水平初速度和竖直初速度就是
Vx=Vy=V= ( 2 E / m ) \sqrt (2E/m) ( 2E/m)
由gt=Vy可得在空中运动时间为Tx=2*t= 2 ∗ V y / g ; 2*Vy/g; 2Vy/g;
所以每次水平前进距离x= V x ∗ T x Vx*Tx VxTx= 2 ∗ V x 2 2*Vx^2 2Vx2/g= 2 E / m g 2E/mg 2E/mg
这样每次只是E减少百分之p。
不过坑点有点多,一个是double转换问题,int/int还是int,懂得自然懂 。另一个问题是精度问题,实际上循环条件要至少小于1e-7次方才能过PAT的测评姬,我比赛时以为保留位就取到0.0001即可,让e>=0.0001,结果精度不够只能过3个样例,吐血,可能累加有的样例让动能损失百分比很小然后累加就能超过。。。
对了比赛甚至忘了浮点保留位格式怎么输出,结果只能自己编一个出来。
ac代码:

#include<iostream>
#include<cstdio>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int main() {
    
    
	int w, p;
	cin >> w >> p;
	double m = w / 100.0;
	double e = 1000;
	double x ;
	double sum = 0;
	while (e >= 1e-9) {
    
    //精度真的坑,当时0.0001还是wa
		x = 2.0 * e / (9.8*m);
		sum += x;
		e = e * (100-p) / 100.0;//注意这里除100的话就为整数了,一定写成100.0
	}
	//printf("%.3lf", sum);//本来应该这么输出结果忘了三位小数怎么表示
	int s = floor(sum * 1000 + 0.5);//因为保留三位乘1000然后四舍五入
	int intger = s / 1000;//整数部分
	int fl = s % 1000;//小数部分
	printf("%d.%d", intger, fl);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43305312/article/details/109024016
013
今日推荐