刷題——Moo University - Financial Aid POJ - 2010

/*
奶牛學校招生,要招n個學生,有c個學生可招,有f元的招生經費
問招生的最大中位值成績是多少,若無法招n個學生輸出-1,n爲奇數
每個學生有成績和招生所需要給的資助


求的是最大中位值成績,先將學生按成績排個序,對於招了那些學生
我們可以看成求招了某個學生
他的前面選n/2個學生的最少招生資助,選n/2個學生的最少招生資助,加上自己的資助小於學校發的,那麼這個學生就可以招收
那麼問題就變成了求這個學生的最大成績
然後二分求解一下
*/
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
struct node{int s,c;};
node e[100005];
bool cmp(node a,node b){
    return a.s<b.s;
}
int n,c,f;
int main(){
    while(~scanf("%d %d %d",&n,&c,&f)){
        for(int i=1;i<=c;i++){
            scanf("%d %d",&e[i].s,&e[i].c);
        }
        sort(e+1,e+1+c,cmp);
        int lb=1,hight=c,ans=-1;
        while(hight-lb>1){
            int mid=(lb+hight)/2;
            int l=0,r=0,sum=e[mid].c;
            priority_queue<int>q1,q2;
            for(int i=1;i<mid;i++){
                l++;
                sum+=e[i].c;
                q1.push(e[i].c);
            }
            while((l>n/2||sum>f)&&!q1.empty()){
                l--;
                sum-=q1.top();
                q1.pop();
            }
            for(int i=c;i>mid;i--){
                r++;
                sum+=e[i].c;
                q2.push(e[i].c);
            }
            while((r>n/2||sum>f)&&!q2.empty()){
                r--;
                sum-=q2.top();
                q2.pop();
            }
            if(l<n/2&&r<n/2){
                ans=-1;
                break;
            }
            else if(l<n/2){
                lb=mid;
            }
            else if(r<n/2){
                hight=mid;
            }
            else{
                ans=e[mid].s;
                lb=mid;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章