uva_11627_Slalom( 二分 )

題意:

題目意思比較就是有n個障礙你必須通過,障礙的左面的座標已經給出,障礙的縱座標單調遞增,你有s個鞋子,每個鞋子的垂直速度是sj, 且你的水平速度不能大於vh,問最快通過所有障礙的鞋子的最大速度是多少?

分析:

由於橫速度恒定,二分枚舉速度。只要將當前障礙到下一個障礙之間的距離分解,然後求出下一個橫區間的範圍,然後判斷這個區間是否為合法區間就得出這個速度是否可行

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAXN    100000 + 10
#define MAXM    1000000 + 10
#define REPI(i, s, e)   for(int i = (s); i <= (e); i ++)

static const double eps = 1e-9;

typedef struct Node_ {
        double x, y;
}Node;

Node gate[MAXN];
int n, s, shoes[MAXM];
double w, vh;


void input(void)
{
        scanf("%lf %lf %d", &w, &vh, &n);
        REPI(i, 1, n) {
                scanf("%lf %lf", &gate[i].x, &gate[i].y);
        }
        scanf("%d", &s);
        REPI(i, 1, s) {
                scanf("%d", &shoes[i]);
        }
        sort(shoes+1, shoes+s+1);
}

int valid(int v)
{
        double l = gate[1].x, r = gate[1].x+w;
        REPI(i, 2, n) {
                double d = vh*(gate[i].y-gate[i-1].y)/(double)v;
                l -= d, r += d;
                l = max(l, gate[i].x);
                r = min(r, gate[i].x+w);
                if( l-r >= eps ) {
                        return 0;
                }
        }
        return 1;
}

int work(void)
{
        int l = 1, r = s, rst = -1;
        while( l <= r ) {
                int m = (l+r)>>0x1;
                if( valid(shoes[m]) ) {
                        rst = max(rst, shoes[m]);
                        l = m+1;
                }
                else {
                        r = m-1;
                }
        }
        return rst;
}

void output(int rst)
{
        if( -1 == rst ) {
                printf("IMPOSSIBLE\n");
                return;
        }
        printf("%d\n", rst);
}

int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
#endif
        int cas;
        scanf("%d", &cas);
        REPI(k, 1, cas) {
                input();
                output(work());
        }
        return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值