UVALive 6835

抛物线过障碍

题目描述:

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值