poj2010 Moo University - Financial Aid 二分

题意: bessie要给牛建一所学校,他的总资金为F,牛的总数为C,总共可以提供N头牛上学,对于每头牛,已知它的分数和bessie需要提供给它的资金,问如何从C头牛中选择N头牛,在资金不超过F的前提下,使这N头牛的分数的中位数最大

思路:由于结果收到分数和资金的共同影响,所以将牛的分数和个人资金以及下标存在结构体中,分别对分数和资金排序,再二分分数的中位数,不断更新即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,s;
struct Z{
int x;
int y;
int z;
}z1[100005],z2[100005];
bool cmp(Z& a,Z& b){
return a.x<b.x;
}
bool cmp1(Z& a,Z& b){
return a.y<b.y;
}
int main(){
cin>>m>>n>>s;
int ans=-1;
for(int i=0;i<n;i++){
    scanf("%d%d",&z1[i].x,&z1[i].y);
}
sort(z1,z1+n,cmp);
for(int i=0;i<n;i++){
    z1[i].z=z2[i].z=i;
    z2[i].x=z1[i].x;
    z2[i].y=z1[i].y;
}
memcpy(z2, z1, sizeof(Z) * n);
sort(z2,z2+n,cmp1);
int l=0,r=n;
while(r-l>1){
    int mid=(l+r)/2;
     int sum=z1[mid].y;
     int left=0,right=0;
     for(int i=0;i<n;++i){
        if((z2[i].z<mid)&&(sum+z2[i].y<=s)&&(left<m/2)){
            left++;
            sum+=z2[i].y;
        }
        else if((z2[i].z>mid)&&(z2[i].y+sum<=s)&&(right<m/2)){
            sum+=z2[i].y;
            right++;
        }
     }
        if((left<m/2)&&(right<m/2)){
            ans=-1;
            break;
        }
        else if(left<m/2)
               l=mid;
        else if(right<m/2)
              r=mid;
        else {
            ans=z1[mid].x;
            l=mid;
        }
}
 cout<<ans<<endl;
}


阅读更多
文章标签: ACM poj 算法
个人分类: poj 二分
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭