ZOJ 4062 Plants vs. Zombies 2018 ICPC 青岛站 E Plants vs. Zombies

ZOJ 4062

二分

哎,二分,二分,二分,我咋就没想到啊,在一篇博客上看到一句话:

一般此类最小值最大问题都是二分,此题显然也是可以二分植物的高度的。

博客链接:https://www.cnblogs.com/mountaink/p/9921988.html

就是直接二分答案,然后判断行了,如果满足题意,l=mid+1,继续判断,如果不满足题意,r=mid-1。

其他的就是注意一下当i等n的时候,还有就是注意用long long,其他的真的没什么了,哎,2018年ICPC青岛站的铜牌题,真的是太简单了,做的时候没想到是二分,想到了这个题真的超级简单啊,还是太菜了......

ACcode

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<sstream>
#include<cstdlib>
#include<time.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define repp(i,n,a) for(int i=n;i>=a;i--)
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define Eps 1e-8
#define Mod 1000000000
typedef long long ll;
typedef unsigned long long ull;
const double pi=acos(-1.0);
using namespace std;
const int N=100010;
ll a[100010];
ll b[100010];
ll n,m;
bool ok(ll x)
{
    ll p=m;
    for(int i=1;i<=n;i++)
        b[i]=0;
    for(int i=1;i<=n;i++)
    {
        if(i==n&&a[i]*b[i]>=x)
            return true;
        p--;
        b[i]++;
        if(p<0)
            return false;
        if(a[i]*b[i]>=x)
            continue;
        if((x-a[i]*b[i])%a[i]==0)
        {
            p-=((x-a[i]*b[i])/a[i])*2;
            b[i+1]+=((x-a[i]*b[i])/a[i]);
            b[i]+=((x-a[i]*b[i])/a[i]);
        }
        else
        {
            p-=((x-a[i]*b[i])/a[i]+1)*2;
            b[i+1]+=((x-a[i]*b[i])/a[i]+1);
            b[i]+=((x-a[i]*b[i])/a[i]+1);
        }
        if(p<0)
            return false;
    }
    return true;
}
int main()
{
    int T;  scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld",&n,&m);
        ll minn=100010;
        for(int i=1;i<=n;i++)
            {scanf("%lld",&a[i]);minn=min(minn,a[i]);}
        ll l=0,r=m*minn;
        ll ans=0;
        while(l<=r)
        {
            ll mid=(l+r)/2;
            if(ok(mid))
                {l=mid+1;ans=max(ans,mid);}
            else
                r=mid-1;
        }
        if(ok(l-1))
            ans=max(ans,l-1);
        if(ok(r-1))
            ans=max(ans,r-1);
        if(ok(l))
            ans=max(ans,l);
        if(ok(r))
            ans=max(ans,r);
        if(ok(l+1))
            ans=max(ans,l+1);
        if(ok(r+1))
            ans=max(ans,r+1);
        if(ok(l+2))
            ans=max(ans,l+2);
        if(ok(r+2))
            ans=max(ans,r+2);
        printf("%lld\n",ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值