POJ2010--Moo University-Financial Aid(二分)

来源:互联网 发布:android淘宝分类菜单 编辑:程序博客网 时间:2024/05/16 16:23

题目大意:在C头牛里选N头牛,在不超过经费F的情况下,使得N头牛的得分中位数最大。


分析:首先,既然有两个属性,我们可以分别开两个数组,一个数组按成绩升序,一个数组按经费升序。二分中位数那头牛mid,然后按经费从少到多,添加mid两边的牛。再进行判断,四种情况,见代码。


代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 222222;struct Cow{    int rank, score, aid;};Cow c_aid[maxn], c_score[maxn];int N, C, F;bool cmpa(Cow & i, Cow & j) {    return i.aid < j.aid;}bool cmps(Cow & i, Cow & j) {    return i.score < j.score;}int main() {    while(~scanf("%d%d%d", &N, &C, &F)) {        for(int i = 0; i < C; i++)            scanf("%d%d", &c_score[i].score, &c_score[i].aid);        sort(c_score, c_score+C, cmps);        for(int i = 0; i < C; i++)            c_score[i].rank = i;        memcpy(c_aid, c_score, sizeof(Cow)*C);        sort(c_aid, c_aid+C, cmpa);        int L = 0, R = C, ans = -1;        while(R-L > 1) {            int mid = (L+R)>>1;            int left = 0, right = 0, tot = c_score[mid].aid;            for(int i = 0; i < C; i++) {                if((c_aid[i].rank < mid) && (tot+c_aid[i].aid <= F) && (left < N/2)) {                    tot += c_aid[i].aid;                    left++;                }                else if((c_aid[i].rank > mid) && (tot+c_aid[i].aid <= F) && (right < N/2)) {                    tot += c_aid[i].aid;                    right++;                }            }            if(left < N/2 && right < N/2) {                ans = -1;                break;            }            else if(left < N/2) L = mid;            else if(right < N/2) R = mid;            else ans = c_score[mid].score, L = mid;        }        printf("%d\n", ans);    }    return 0;}



0 0
原创粉丝点击