zoukankan      html  css  js  c++  java
  • CodeForces Gym

    题目链接:https://vjudge.net/contest/236677#problem/G

    题目意思:有m个地方,有k小时,每个地方有a[i]个人。你要进行操作(一个小时可以移动一个人到另一个地方,或者不移动),最后使得m个地方的人数最多值变成最小情况。(就是移动人使每个地方的人接近平均值,就是统计学中方差就小)

    思路:求出平均值,因为平均值是不变的,答案一定在平均值和最大值之间,二分就是要找到这个区间,左边临界值就是平均值,右边临界值就是最大值。在与当前最大值maxx二分得平局值mid,比较大于mid的地方移动到mid的时间总和是否比当前k大。

    1.小于则说明都可以人数到达mid,再将最大人数maxx改为mid,k减去耗费时间,继续二分,直到大于,或者可以到达总平局值为止

    2.大于则扩大均值,再二分,直到均值大于等于最大人数maxx

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int a[100050];
    int m,k;
    long long fun(long long t)//求当前人数最大到达t时间长 
    {
        long long sum=0;
        for(int i=0;i<m;i++)
        {
            if(a[i]>t)
                sum+=a[i]-t;
        }
        return sum;
    }
    int main()
    {
        while(cin>>m>>k)
        {
            long long sum=0,midx,maxx=0;
            for(int i=0;i<m;i++)
            {
                cin>>a[i];
                sum+=a[i];
                if(maxx<a[i])//maxx最大人数 
                    maxx=a[i];
            }
            if(sum%m==0)
                midx=sum/m;
            else
                midx=sum/m+1;//均值 
            long long l=midx,r=maxx;
            while(l<r)//二分 
            {
                int mid=(l+r)/2;
                if(fun(mid)<=k)//可以达到均值,maxx(右)移动到mid 
                    r=mid;
                else//不可以达到均值,midx(左)移动到mid+1; 
                    l=mid+1;
            }
            cout<<l<<endl;
        } 
        return 0;
    }
  • 相关阅读:
    Hive问题
    VirtualBox安装增强功能
    Shell脚本 数据清洗
    团队项目第一阶段冲刺站立会议06
    梦断代码阅读笔记1
    团队项目第一阶段冲刺站立会议05
    团队项目第一阶段冲刺站立会议04
    团队项目第一阶段冲刺站立会议03
    团队项目第一阶段冲刺站立会议02
    团队项目第一阶段冲刺站立会议01
  • 原文地址:https://www.cnblogs.com/xiongtao/p/9277601.html
Copyright © 2011-2022 走看看