本题显然是水题
题目连接: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;
2∗Vy/g;
所以每次水平前进距离x=
V
x
∗
T
x
Vx*Tx
Vx∗Tx=
2
∗
V
x
2
2*Vx^2
2∗Vx2/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;
}