Robin Hood(运用二分法两次)

We all know the impressive story of Robin Hood. Robin Hood uses his archery skills and his wits to steal the money from rich, and return it to the poor.
There are n citizens in Kekoland, each person has c i coins. Each day, Robin Hood will take exactly 1 coin from the richest person in the city and he will give it to the poorest person (poorest person right after taking richest’s 1 coin). In case the choice is not unique, he will select one among them at random. Sadly, Robin Hood is old and want to retire in k days. He decided to spend these last days with helping poor people.
After taking his money are taken by Robin Hood richest person may become poorest person as well, and it might even happen that Robin Hood will give his money back. For example if all people have same number of coins, then next day they will have same number of coins too.
Your task is to find the difference between richest and poorest persons wealth after k days. Note that the choosing at random among richest and poorest doesn’t affect the answer.InputThe first line of the input contains two integers n and k (1 ≤ n ≤ 500 000, 0 ≤ k ≤ 109) — the number of citizens in Kekoland and the number of days left till Robin Hood’s retirement.
The second line contains n integers, the i-th of them is c i (1 ≤ c i ≤ 109) — initial wealth of the i-th person.OutputPrint a single line containing the difference between richest and poorest peoples wealth.Examples
Input
4 1
1 1 4 2
Output
2
Input
3 1
2 2 2
Output
0
题意:这是一个关于劫富济贫的问题,就是缩小贫富差距,有一个大侠每天可以偷一个富人的金币,给穷人,并且k天后便退休不在干了,问最后的贫富差距。
解题思路:要使最后的贫富差距最小,那么的话,也就是求最大值的最小值,最小值得最大值;所以求第一个的时候可以用一个二分法来求,第二个也用一个二分法来求,最后再相减即可。
解题步骤
1)首先的对存入每个人贫富用sort函数进行从小到大进行排序,这样便知道开始时最大和最小的 ;
2)首先利用一次二分算法,将最大值的最小值找出来,也就是劫富济贫之后的最大值,第一富人;
3)再一次利用二分算法将最小值的最大值,也就是通过救济之后的穷人的钱财;
4)注意,劫富济贫的钱财不能超过天数,因为他每天只能偷一个;也就是每天只有一个金币流转;

#include <iostream>
#include <algorithm>
using namespace std;
int n;
long long k,a[500005];
int main()
{
    while(cin>>n>>k)
        {
            for(int i=0;i<n;i++)
                 cin>>a[i];
            sort(a,a+n);
            int max=a[n-1],min=a[0];
            int low=min,high=max;
            while(low<=high)
                {
                    int mid=(low+high)/2;
                    long long k1=0,c=0;
                    for(int i=0;i<n;i++)
                        {
                            if(a[i]>mid)
                               k1+=(a[i]-mid);
                            else c+=(mid-a[i]);
                        }
                    if(k1<=k&&c>=k1)
                        {
                            high=mid-1;
                            max=mid;
                        }
                    else low=mid+1;
                }
            low=0,high=a[n-1];
            while(low<=high)
                {
                    int mid=(low+high)/2;
                    long long k2=0,c1=0;
                    for(int i=0;i<n;i++)
                        {
                            if(a[i]<mid) k2+=(mid-a[i]);
                            else c1+=(a[i]-mid);
                        }
                    if(k2<=k&&c1>=k2)
                        {
                            low=mid+1;
                            min=mid;
                        }
                    else high=mid-1;
                }
            cout<<max-min<<endl;
        }
    return 0;
}
### 回答1: robin_hood::unordered_set是一种基于开放寻址的哈希表实现,它是C++ STL中的一个无序集合容器。与标准的unordered_set相比,robin_hood::unordered_set有着更高的性能。 robin_hood::unordered_set的实现方式采用了"robin hood"哈希算法,这种算法通过再哈希的方式处理冲突,将冲突的元素移到更远的位置,从而保持高效的查找性能。这种算法使得插入和删除操作具有O(1)的时间复杂度,而查找操作虽然在最坏情况下也是O(n),但实际上在大多数情况下是O(1)的。 此外,robin_hood::unordered_set在内存使用上也比标准的unordered_set更为高效。它采用了连续的内存布局,并使用了布隆过滤器来减少哈希冲突的数量,从而减少了内存的占用。 使用robin_hood::unordered_set时,可以通过插入、删除和查找等操作来管理集合中的元素。插入操作可以将元素添加到集合中,删除操作可以从集合中移除指定的元素,而查找操作可以判断集合中是否存在某个元素。 总的来说,robin_hood::unordered_set是一种高效的无序集合容器,适用于需要频繁进行插入、删除和查找操作的场景。它通过"robin hood"哈希算法和优化的内存使用方式,在性能和内存占用方面均有优势。 ### 回答2: Robin Hood是一个著名的英雄人物,他以偷取富人财物来帮助穷人而闻名。而unordered_set是C++ STL库中的一个数据结构,它是一个无序的集合,允许快速地插入、查找和删除元素。 尽管二者似乎没有直接联系,但是我们可以通过一些类比来理解它们之间的关系。就像Robin Hood通过偷取富人的财物来帮助穷人一样,unordered_set可以用来解决一些问题,比如查找和删除元素,这些问题在其他数据结构中可能需要更多的时间和资源。 就像Robin Hood能够迅速地从富人身上夺取财物,unordered_set在最佳情况下能够以O(1)的时间复杂度插入、查找和删除元素,这取决于哈希函数的性能。这使得它在一些需要高效率操作的场景中非常有用,比如去重、查找等。 然而,就像Robin Hood有时候可能会遇到困难一样,unordered_set也有一些限制。由于其无序的特点,它在有序访问元素方面相对较弱。此外,当元素数量较大时,哈希冲突的概率也会增加,导致性能下降。因此,在某些情况下,我们可能需要考虑使用其他更适合的数据结构。 总之,尽管Robin Hood和unordered_set在本质上是不同的,但通过类比,我们可以更好地理解unordered_set的特点和用途。无论是Robin Hood还是unordered_set,它们都有自己独特的功能和限制,我们需要根据具体的问题和需求来选择使用它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值