Gym - 100989G (二分法)

There are K hours left before Agent Mahone leaves Amman! Hammouri doesn‘t like how things are going in the mission and he doesn‘t want to fail again. Some places have too many students covering them, while other places have only few students.

Whenever Hammouri commands a student to change his place, it takes the student exactly one hour to reach the new place. Hammouri waits until he is sure that the student has arrived to the new place before he issues a new command. Therefore, only one student can change his place in each hour.

Hammouri wants to command the students to change their places such that after K hours, the maximum number of students covering the same place is minimized.

Given the number of students covering each place, your task is to find the maximum number of students covering the same place after K hours, assuming that Hammouri correctly minimizes this number.

Input

The first line of input contains two integers M (2?≤?M?≤?105) and K (1?≤?K?≤?109), where M is the number of places and K is the number of hours left before Agent Mahone leaves Amman.

The second line contains M non-negative integers, each represents the number of students covering one of the places. Each place is covered by at most 109 students.

Output

Print the maximum number of students covering a place after K hours, assuming that Hammouri minimized this number as much as possible in the last K hours.

Examples

Input

5 43 4 1 4 9

Output

5

Input

2 10000000001000000000 4

Output

500000002

Input

5 32 2 2 2 1

Output

2

题意:给了你n个数和一个时间,一个单位时间可以修改一次数据,修改的方法是将n个数中的某一个加1,而另一个减1(相当于把某个数的1送给另一个数),问你在规定时间内如何修改这n个数,可以使得这n个数中的最大值是所有修改方法中最小的,输出最小值。

思路:大佬的思路,不知道大佬的脑子是什么做的,这都能想出来(应该是我太菜)!!!首先要明确一点,这n个数不管如何修改,最后的最大值一定大于等于这n个数的平均值,而且一定小于等于没修改前的最大值,所以最后的答案一定在这两者之间。所以我们就可以用二分法对这两者之间的所有数进行二分查找。查找的每一次都需要判断是否符合要求:遍历所有的数,记录下这些数中比当前二分的中间值mid大的数,他们与mid的差的和是多少,如果和比你所拥有的时间多,说明不符合要求,你无法将所有的数都修改到中间值这么小,你的答案要比这个中间值大,所以二分的左边界low变成mid+1;否则右边界变成mid-1,一直到最后high<low结束查找。具体看代码:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int main()
{
    ll n,hour,num[100005];
    while(cin>>n>>hour)
    {
        ll sum = 0,aver,Max = -1;
        for(int i=0; i<n; ++i)
        {
            scanf("%lld",&num[i]);
            sum += num[i]; //求出所有数的和
            if(num[i] > Max) //求所有数的最大值
                Max = num[i];
        }
        if(sum%n == 0) //求平均值
            aver = sum/n;
        else aver = sum/n +1;

        ll flag = 0,low = aver,high = Max,mid,all; //初始化二分的左边界为平均值,右边界为最大值
        while(low <= high) //二分
        {
            all = 0;
            mid = (high + low) / 2; //求二分的中间值
            for(int i=0; i<n; ++i)
            {
                if(num[i] > mid) //求出所有比中间值大的数与中间值的差的和
                    all += num[i] - mid;
            }
            if(all == hour) //如果这个和刚好与拥有的时间相等,则不需要查找了,这就是答案
            {
                flag = 1;
                break;
            }
            else if(all > hour) low = mid + 1; //如果和比中间值大,则答案在比中间值大的范围内
            else high = mid - 1; //否则,答案在比中间值小的范围内
        }
        if(flag)
            cout<<mid<<endl;
        else
            cout<<low<<endl;
    }
    return 0;
}


原文地址:https://www.cnblogs.com/tuyang1129/p/9279426.html

时间: 2024-10-12 19:56:37

Gym - 100989G (二分法)的相关文章

CodeForces Gym - 100989G(二分)

题目链接:https://vjudge.net/contest/236677#problem/G 题目意思:有m个地方,有k小时,每个地方有a[i]个人.你要进行操作(一个小时可以移动一个人到另一个地方,或者不移动),最后使得m个地方的人数最多值变成最小情况.(就是移动人使每个地方的人接近平均值,就是统计学中方差就小) 思路:求出平均值,因为平均值是不变的,答案一定在平均值和最大值之间,二分就是要找到这个区间,左边临界值就是平均值,右边临界值就是最大值.在与当前最大值maxx二分得平局值mid,

Gym - 100989G

There are K hours left before Agent Mahone leaves Amman! Hammouri doesn't like how things are going in the mission and he doesn't want to fail again. Some places have too many students covering them, while other places have only few students. Wheneve

Gym 101246H ``North-East&#39;&#39;(LIS)

http://codeforces.com/gym/101246/problem/H 题意: 给出n个点的坐标,现在有一个乐队,他可以从任一点出发,但是只能往右上方走(包括右方和上方),要经过尽量多的点.输出它可能经过的点和一定会经过的点. 思路: 分析一下第一个案例,在坐标图上画出来,可以发现,他最多可以经过4个点,有两种方法可以走. 观察一下,就可以发现这道题目就是要我们求一个LIS. 首先,对输入数据排一下顺序,x小的排前,相等时则将y大的优先排前面. 用二分法求LIS,这样在d数组中就可

day05匿名函数,内置函数,二分法,递归,模块

yield作为表达式来使用的方式 #grep -rl 'python /root """ 查找root下文件中含有python的文件 """ import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def search(target): while True: search

CodeForces Gym 100935D Enormous Carpet 快速幂取模

Enormous Carpet Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 100935D Description standard input/outputStatements Ameer is an upcoming and pretty talented problem solver who loves to solve problems using computers.

Python写个二分法查找

笔者是一个通信测试攻城狮,之前做过一段时间的持续集成.工作内容只要就是对主线版本进行基本通信功能守护,测试执行都是自动化完成,也是那个时候开始接触到代码. 当时经常遇到的一个问题是:某一天我们发现版本有重大BUG,但是到上一次我们验证PASS中间已经经历过很多版本,我们需要手动从中间找到第一个出现BUG的版本,当然最简单的方法是二分法,取中间版本,根据有没有BUG再缩小范围,继续取中间版本...当时我的想法就是思路很固定,完全可以自动化完成,可惜当时我不会写代码...直到今天看Python递归函

B - Average Gym - 101161B 组合数学

http://codeforces.com/gym/101161/attachments 今天被卡常了,其实是自己对组合数技巧研究的不够. 如果是n, m <= 1e5的,然后取模是质数,那么可以用费马小定理. 如果n, m都比较小,那么其实是直接杨辉三角.不用逆元那些. 这题的思路是,枚举每一一个ave,然后总和就是n * ave 相当于方程  x1 + x2 + .... + xn = n * ave中,在0 <= x[i] <= full的情况下,不同解的个数中,使得x[i] ==

Codeforces Gym 100269 Dwarf Tower (最短路)

题目连接: http://codeforces.com/gym/100269/attachments Description Little Vasya is playing a new game named "Dwarf Tower". In this game there are n different items,which you can put on your dwarf character. Items are numbered from 1 to n. Vasya want

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma