【NOIP2015模拟11.3晚】JZOJ7月29日提高组T1 爬山

【NOIP2015模拟11.3晚】JZOJ7月29日提高组T1 爬山

题目

在这里插入图片描述

题意

有一个点在第1分钟位于 a a a这个位置
从第2~ n n n分钟可以向上或向下走最多 d d d的高度
要求在第 n n n分钟结束后到达 b b b这个位置,求能到达的最高高度

分析

先考虑 O ( n ) O(n) O(n)
设当前高度为 x x x
很显然对于一个 i ( 2 ≤ i ≤ n ) i(2≤i≤n) i(2in),如果是合法的,满足 x + d − d ∗ ( n − i ) ≤ b x+d-d*(n-i)≤b x+dd(ni)b
如果成立,答案和 x + d x+d x+d m a x max max
如果不成立,那么最高高度只能是 b + d ∗ ( n − i ) b+d*(n-i) b+d(ni),和答案取 m a x max max
但是看到 n n n是小于等于1012的, O ( n ) O(n) O(n)是过不去的,考虑优化
我们可以二分求出最大的 i i i使得 a + d ∗ ( i − 1 ) − d ∗ ( n − i ) ≤ b a+d*(i-1)-d*(n-i)≤b a+d(i1)d(ni)b成立,这样的话时间就是 O ( l o g ( n ) ) O(log(n)) O(log(n))

Code

#include<cstdio>
#include<iostream>
using namespace std;
long long i,n,d,a,b,l,r,mid,ans;
int main()
{
    freopen("mountain.in","r",stdin);
    freopen("mountain.out","w",stdout);
    scanf("%lld%lld%lld%lld",&n,&d,&a,&b);
    l=2;
    r=n;
    while (l<=r)
    {
        mid=(l+r)>>1;
        if (a+d*(mid-1)-d*(n-mid)<=b)
        {
            l=mid+1;
            ans=max(ans,a+d*(mid-1));
        }
        else 
        {
            r=mid-1;
            ans=max(ans,b+d*(n-mid));
        }
    }
    printf("%lld\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值