刷题——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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章