D. Salary Changing(找中位數)


題:https://codeforces.com/contest/1251/problem/D

題意:給你n個單位需要滿足達到的區間,再給個s,s是要分配給n的單位的量,當然∑l<=s,問經過分配后能夠達到的最大中位數是多少

題解:二分找中位數,成立原因:代碼注釋

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=b;i>=a;i--)
#define pb push_back
#define pll pair<ll,ll>

const int inf=0x3f3f3f3f;
const ll INF=1e18;
vector<pll>a;
int n;
ll s;
ll check(ll m){///挑出能達到中位數midd的都要達到中位數和已經比中位數大的數,且只能取一半+1個 
///因為a 已經按照從大到小排序了,所以從前往后地挑出能達到midd的來加肯定是耗錢最少的 
    int countt=a.size()/2+1;
    ll sum=0;
    for(int i=0;i<a.size();i++){
        if(a[i].first<=m&&a[i].second>=m&&countt){
            sum+=m;
            countt--;
        }
        else{
            sum+=a[i].first;
            if(a[i].first>m)
                countt--; 
        }
    }
    if(countt)
        return s+10;//讓這一步不合法 
    else
        return sum;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%d%I64d",&n,&s);
        a.clear();
        fo(i,1,n){    
            ll x,y;
            scanf("%I64d%I64d",&x,&y);
            a.pb(make_pair(x,y));
        }
        
        sort(a.begin(),a.end());
        reverse(a.begin(),a.end());
        ll l=a[a.size()/2].first+1,r=s;
        while(l<=r){
            ll midd=(l+r)>>1;
            if(check(midd)<=s)
                l=midd+1;
            else
                r=midd-1;
        }
        printf("%I64d\n",l-1);
    }
    return 0;
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM