您的位置:首页 > 其它

UVALive 6835

2015-05-16 21:27 134 查看

抛物线过障碍

题目描述:

n~10个障碍物,一个球从a要求弹到b,然后中间一共弹小于c~15次,重力g=1,问可以越过障碍物最小的初速度是多少?

题解:

关键是枚举判定。先枚举几次,定出了两点,然后想出擦边走最好,那么枚举擦哪一个点,然后判定是否可以选最小的。但是记住45度是最好的,当障碍物太低的时候没必要擦边,45度走

重点:

45度走最好。枚举判定

代码:

//轩哥的代码

#include <cstdio>
#include <algorithm>
#include <cmath>
#define EPS 1e-9
using namespace std;
double p[32], h[32];
bool flag;
int main() {
int n, b, doub, doubPre;
double d, dist, mul, ans;
while (~scanf("%lf%d%d", &d, &n, &b)) {
for (int i = 0; i < n; ++i)
scanf("%lf%lf", &p[i], &h[i]);
ans = -1;
for (int i = 0; i <= b; ++i) {//首先枚举跳几次,可以获得两个点
dist = d / (i+1);//45度的一定要特判。因为不在擦边走的范围内
mul = -1.0/dist;
flag = true;
for (int t = 0; t < n; ++t) {
doub = (int) ((p[t] / dist)+EPS);
//printf("pre---h[t]%f\n", mul*(p[t]- doub*dist)*(p[t] - (doub+1)*dist));
if (mul*(p[t]- doub*dist)*(p[t] - (doub+1)*dist) < h[t] - EPS) {
//printf("h can't pass------%d\n", h[t]);
flag = false;
//printf("lll\n");
break;
}
}
if (flag) {
if ((ans + 1.0) < EPS)
ans = sqrt(-0.5/mul - mul*dist*dist/2.0);
else
ans = min(ans,sqrt(-0.5/mul - mul*dist*dist/2.0));
}
else {//45度的不能,那么就只能擦边走了
for (int j = 0; j < n; ++j) {//枚举擦边谁,然后两根式确定抛物线,然后求出抛物线枚举判定
doubPre = (int) ((p[j] / dist)+EPS);
mul = h[j] / (p[j] - doubPre*dist) / (p[j] - (doubPre+1)*dist);
flag = true;
//printf("--- mul %f----dist %f----\n", mul, dist);
for (int t = 0; t < n; ++t) {
doub = (int) ((p[t] / dist)+EPS);
//printf("beishu----%d\n", doub);
//printf("-----h[t]%f\n", mul*(p[t]- doub*dist)*(p[t] - (doub+1)*dist));
if (mul*(p[t]- doub*dist)*(p[t] - (doub+1)*dist) < h[t] - EPS) {
//  printf("h------%d\n", h[t]);
flag = false;
//  printf("lll\n");
break;
}
}
if (flag) {
//printf("okokok----- mul %f----dist %f----\n", mul, dist);
//printf("vx---%f   vy----%f\n", sqrt(-0.5/mul), sqrt(-mul*dist*dist/2.0));
if ((ans + 1.0) < EPS)
ans = sqrt(-0.5/mul - mul*dist*dist/2.0);
else
ans = min(ans,sqrt(-0.5/mul - mul*dist*dist/2.0));
}
}
}
}
printf("%f\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: