• 2016级算法期末模拟练习赛-C.AlvinZH的青春记忆II


    1084 AlvinZH的青春记忆II

    思路

    中等题,二分。

    简化题意,一列数字,每秒会自动-1,特殊操作可以使一个数在1s内-k,问这些数都减至0需要多久。

    答案肯定在[1,xMax]之间,采用二分的方法找到最小时间。

    如何判断一个时间值是否符合要求呢?对于≤mid的数,自然消减就好,对于>mid的数,需要特殊操作,设特殊操作次数为s,则有 (k*s + (mid-s) = Xi),解得 (s = (X[i]-mid) / (k-1))

    分析

    注意三个问题,

    第一,除0问题,k-1可能为0,需要提前特判,如果k==1,那个和自然递减没有差别,答案直接输出xMax。

    第二,式子中有可能会出现小数,如何处理?向上取整!(s = ceil(1.0*(X[i]-mid) / (k-1)))

    第三,计算过程中s需要多次叠加,有可能会超过int范围,需要使用long long。

    参考代码

    //
    // Created by AlvinZH on 2017/12/9.
    // Copyright (c) AlvinZH. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    int n, k;
    int X[100000+10];
    int Xmax;
    
    int main ()
    {
        while(~scanf("%d %d", &n, &k))
        {
            Xmax = 0;
            for(int i = 0; i < n; i++)
            {
                scanf("%d", &X[i]);
                if(X[i] > Xmax)
                    Xmax = X[i];
            }
            if(k == 1)
            {
                printf("%d
    ", Xmax);
                continue;
            }
    
            int ans = 0;
            int l = 1, r = Xmax, mid;
            while (r >= l)
            {
                mid = (l+r)/2;
    
                long long cnt = 0;
                for (int i = 0; i < n; i++)
                {
                    if(X[i] > mid)
                    {
                        long long s = ceil(1.0*(X[i]-mid) / (k-1));
                        cnt += s;
                    }
                }
                if (cnt > mid)
                    l = mid+1;
                else
                    r = mid-1, ans = mid;
            }
            printf ("%d
    ", ans);
        }
    }
    
  • 相关阅读:
    SVN 图标消失
    svn 图标不显示
    wamp 局域网访问
    php程序 注册机制
    ThinkphpCMF笔记
    thinkphp缓存
    wampserver与 thinkphp 安装
    js function集合
    php function集合
    php sleep
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/8137719.html
Copyright © 2020-2023  润新知