zoukankan      html  css  js  c++  java
  • ZOJ4062 Plants vs Zombies(二分)

    题意:

    有一排植物,初始高度是0。机器人从坐标轴0处出发,最多走k步,每走过一株植物,该植物的能量增加i(i为植物的坐标)。问怎么安排机器人的路线使得植物中最少的能量最大,并输出那个值。

    题解:

    二分查找,枚举所有可能的能量值。

    每次check,先计算以x为最小值的情况下,每个位置至少要走几步。

    然后模拟一边机器人浇水的过程看能否实现。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    typedef long long ll;
    int T;
    int N; 
    ll m;
    ll a[maxn],b[maxn];
    int check (ll x) {
        ll step=0;
        for (int i=0;i<N;i++) {
            //先算一遍以x为最小值的情况下,每个位置至少要走多少步
            b[i]=(x+a[i]-1)/a[i]; 
        } 
        for (int i=0;i<N-1;i++) {
            step++;//每走到一个位置就加一步 
            b[i]--;
            if (b[i]<=0) continue;
            step+=2*b[i];
            //每次想要再走一遍当前位置的话,必然是继续往前走再走回来,需要两倍的步数
            b[i+1]-=b[i];//因为b[i]的步数剪掉
            if (step>m) return 0; 
        } 
        if (b[N-1]>0) {
            step++;
            b[N-1]--;
            step+=b[N-1]*2;
        }
        if (step>m) return 0;
        return 1;
    }
    
    int main () {
        scanf("%d",&T);
        while (T--) {
            scanf("%d%lld",&N,&m);
            for (int i=0;i<N;i++)
                scanf("%lld",&a[i]);
            ll l=0,r=1e12+10;
            ll ans=0;
            while (l<r) {
                ll mid=(l+r)>>1;
                if (check(mid)) {
                    ans=mid;
                    l=mid+1;
                }
                else r=mid;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    PAT:1006(换个格式输出整数想&#183;)
    PAT 1008(数组循环右移问题)
    kaliLinux 工具dmitry参数解析
    PAT 1004(成绩排名)(C++)
    PAT乙级:我要通过(1003)
    PAT乙级:写出这个数(1002)
    PAT乙级:(3n+1)猜想 (1001)
    Linux初体验
    C语言基础入门:起源
    Linux_ pipe 匿名管道 浅解
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12505944.html
Copyright © 2011-2022 走看看