codeforces 785c[补]

真的是。。越来越菜了。拿到一道题过不了心态就爆炸。

题目:http://codeforces.com/problemset/problem/785/C
题目意思:
有一个仓库。容量为n,每天会补充m的粮仓,如果补的库存量加上仓库原有库量超过了容量,仓库里的库存量就为n,每一天都会有小鸟来啄走粮食,每个小鸟每天就只能啄走1个单位的粮食,但每过一天就会多一只小鸟,现在问这个仓库的粮仓什么可以支持多少天后库存量为0,注意:是小鸟先啄食,再补粮仓。

拿到题感觉很准,不就是一道公式题嘛,求一个不等式的解,向上取整,于是默默的列出了一个不等式
n - d * (d + 1) / 2 + (d - 1) * m >= 0
没错就是这个不等式。。让我搞了一个晚上。。不知道为什么当时脑抽的加上了(d - 1) * m。。明明我的d是应该从m天以后开始的,就不需要加(d - 1) * m了

这是wa了一个晚上的想法。。下面说说这题的正解
当m >= n的时候,每次都肯定可以补满粮仓,所以只有当小鸟数到达n的时候,才能将粮仓清零,所以这种情况的答案应该是n
当m < n时,第m天前,所有粮仓库存量都是可以补满的,所以只需要管后面还需要多少天即可。
可以列出不等式n - m - d * (d + 1) / 2 < 0,表示n的库存量,在第d天的时候库存量要小于0,求最小的那个d, 很容易可以解出方程为-0.5 + sqrt(0.25 + 2 * (n - m)),但是很遗憾,sqrt这个只是double,精度并不够,所以有个队友提出了。。二分。
二分去check他这个式子是否满足(由于这个式子是单调递减的,所以可以选择使用二分),还有一点很重要的d * (d + 1)这个会爆ll的,所以应该先除后乘,但是依旧遇到很奇怪的事情,除2也会爆ll,所以我选择了*0.5。。这难道就是魔法。

后来又想,怎么才能解决爆精度的问题,于是想到,再check一次答案而否正确,不正确的话,天数就得+1,因为有一点点的精度问题嘛。

代码:

二分:

/*
@resouces: codeforces
@date: 2017-3-17
@author: QuanQqqqq
@algorithm: 
*/
#include <bits/stdc++.h>

#define ll long long
using namespace std;

ll n,m;

ll check(ll day){
    return -day * 0.5 * (day + 1) + n - m <= 0; 
}

ll binary_search(ll l,ll r){
    ll mid,ans;
    while(l <= r){
        mid = l + r >> 1;
        if(check(mid)){
            r = mid - 1;
            ans = mid;
        } else {
            l = mid + 1;
        }
    }
    return ans;
}

int main(){
    while(~scanf("%lld %lld",&n,&m)){
        if(n <= m){
            printf("%lld\n",n);
            continue;
        }
        printf("%lld\n",binary_search(0,1e18) + m);
    }
}

公式法:

#include <bits/stdc++.h>

#define ll long long
using namespace std;

int main(){
    ll n,m;
    while(~scanf("%lld %lld",&n,&m)){
        if(n <= m){
            printf("%lld\n",n);
            continue;
        }
        ll ans = (ll)ceil(-0.5 + sqrt(0.25 + 2 * (n - m)));
        if(ans * ans + ans - 2 * (n - m) < 0){
            ans++;
        }
        printf("%lld\n",m + ans);
    }
    return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值