1. 程式人生 > >Gym - 100989G (二分法)

Gym - 100989G (二分法)

ati imu algorithm left 求平均值 print ron output can

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 4
3 4 1 4 9
Output
5
Input
2 1000000000
1000000000 4
Output
500000002
Input
5 3
2 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;
}


Gym - 100989G (二分法)