• 2018ACM/ICPC 青岛现场赛 E题 Plants vs. Zombies


    题意:

    你的房子在0点,1,2,3,...,n(n<=1e5)点每个点都有一颗高度为0的花,浇一次水花会长a[i]。

    你有一个机器人刚开始在你家,最多走m步,每一步只能往前走或者往后走,每走到一个地方除了房子都会给花浇水,问m步以后最低那朵花的高度最大是多少。

    思路:二分,并且可以证明左右横跳(即这一个点不够我们就来回走一直到够高度为止)。

    需要注意步数用完直接break,每一朵花浇够次数立刻走向下一朵花(如果还有步数)。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 200010
    using namespace std;
    ll n,m,k;
    ll c[maxn],a[maxn];
    ll ans,tmp,sum;
    inline ll read(){
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
     
    inline void print(ll x){
        if(x<0){
            putchar('-');
            x=-x;
        }
        if(x>9)
            print(x/10);
        putchar(x%10+'0');
    }
    bool jud(ll mid)
    {
        for(int i=1;i<=n;i++) c[i]=0;
        ll cnt=m-1;c[1]=a[1];
        int i=1;
        for(;i<=n;i++)
        if(i<n){
            if(cnt==0) break;
            ll tmp=(mid-c[i]+a[i]-1)/a[i];
            if(tmp<=0) {cnt--;c[i+1]+=a[i+1];continue;}
            if(cnt<tmp*2) break;
            cnt-=tmp*2;
            c[i]+=a[i]*tmp;
            c[i+1]+=a[i+1]*tmp;
            if(cnt==0) break;
            cnt--;
            c[i+1]+=a[i+1];
            if(cnt==0) break;
        }
        else
        {
            if(cnt==0) break;
            if(c[i]>=mid) break;
            else
            {
                ll tmp=(mid-c[i]+a[i]-1)/a[i];
                if(cnt<tmp*2) return 0;
                else c[i]+=a[i]*tmp;
            }
        }
        for(;i<=n;i++)if(c[i]<mid) return 0;
        return 1;
    }
    int main()
    {
        ll T,cas=1;
        T=read();
        while(T--)
        {
            n=read();m=read();
            ll l=0,r=m;
            for(int i=1;i<=n;i++)
            {a[i]=read();
            if(r<m*a[i]) r=m*a[i];
            }
            if(m==0) {puts("0");continue;}
            ll ans=r;
            while(l<r)
            {
                ll mid=(l+r)/2;
                if(jud(mid)) {l=mid+1;ans=mid;}
                else r=mid;
            }
            print(ans);
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    java中的接口
    java中的多态
    java中的继承
    抽象和封装
    表单验证
    13、迭代器与生成器
    10、end关键字和Fibonacci series: 斐波纳契数列
    9、字典
    8、元组
    2、Python_Day_1_作业
  • 原文地址:https://www.cnblogs.com/unknownname/p/9947766.html
Copyright © 2020-2023  润新知