CodeForces - 1251D (貪心+二分)

題意

https://vjudge.net/problem/CodeForces-1251Dhtml

您是一個大型企業的負責人。在您的企業當中共有n位員工爲您工做,並且很是有趣的事是這個n是一個奇數(n不能被2整除)。node

您必須給你的員工分配工資。最初,您有s美圓,而第ii個員工應得的薪水應該是liri之間的一個值。而不管怎麼分配每一個人的工資,您必須使得全部分配的工資的中位數最大。ios

對於一個長度爲奇數的序列,若是要找到他的中位數,就須要先對這個序列進行排序,以後找到中間位置的數字。舉例來講:c++

  • 序列[5,1,10,17,6]的中位數是6
  • 序列[1,2,1]的中位數是1

保證您有足夠的錢來支付最低的工資,即l1+l2++lns。spa

注意,您沒必要把全部的錢都花在員工的開支上。.net

思路

假設符合要求的中位數爲x,首先,按右端點從小到大排序,ri的中位數便是x的上界;按左端點排序,獲得x的下界爲li的中位數。這個很好理解,畫個數軸,基本就是那回事。。而後咱們在x的上下界裏二分,check所花費用是否小於等於s便可。怎麼check呢?考慮貪心,對於ri<x的數,咱們就取li,這樣能夠騰出更多的資金;對於li>x的數,咱們取li,也是爲了騰出更多資金;對於li~ri穿插x的數,咱們先丟一塊兒。經過剛纔的判斷咱們能夠獲得放到x左邊和右邊的個數,如今咱們遍歷穿插的數,若是當前x左邊的個數小於右邊,那麼這個數得用來放到左邊,用最小的li便可;不然放到右邊,用x的值便可。最後還剩一個數,那就是中位數x啦,因此判斷tmp+x<=s便可。htm

代碼

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=200005;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
struct node
{
    ll l,r;
} g[N];
int n;
ll s;
bool cmp1(node a,node b)
{
    return a.l<b.l;
}
bool cmp2(node a,node b)
{
    return a.r<b.r;
}
node gg[N];
bool check(ll x)
{
    ll tmp=0,l=0,r=0,cnt=0;

    for(int i=1; i<=n; i++)
    {
        if(g[i].l>x)
            tmp+=g[i].l,r++;
        else if(g[i].r<x)
        {
            tmp+=g[i].l,l++;
        }
        else
        {
            gg[cnt++]=g[i];
        }
    }
    int i=0,j=cnt-1;
    while(i<j)
    {
        if(l<r)
            tmp+=gg[i].l,l++,i++;
        else
            tmp+=x,r++,j--;
    }
   // cout<<"gg"<<endl;
    return tmp+x<=s;
}
int main()
{
    std::ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>s;
        for(int i=1; i<=n; i++)
        {
            cin>>g[i].l>>g[i].r;
        }
        sort(g+1,g+1+n,cmp2);
        ll R=g[n/2+1].r;
        sort(g+1,g+1+n,cmp1);
        ll L=g[n/2+1].l;
        ll l=L,r=R,mid,ans=L;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid))
            {
                l=mid+1;
                ans=mid;
            }
            else
                r=mid-1;
        }
        cout<<ans<<endl;
    }
    return 0;
}
相關文章
相關標籤/搜索