zoukankan      html  css  js  c++  java
  • 堆 poj 2010

    选n个人从c个中 花费不超过f

    c个人的成绩和花费

    求分数中位数最大 n是奇数

    显然中位数是n/2+1 ~c-n/2之间的(假如存在的话)

    用大顶堆维护前n/2个小的花费 求出以这个人为中位数的花费

    同理求出后面n/2个人的最小花费

    然后判断一下即可

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    #define MAXN 100010
    
    struct cow
    {
        int l,r,sc,co;
    }x[MAXN];
    
    struct node//大顶堆
    {
        int Size;
        int z[MAXN];
        void clear()
        {
            Size=0;
            memset(z,0,sizeof(z));
        }
        bool empty()
        {
            return Size?0:1;
        }
        void shift_up(int a)
        {
            while(a>1)
            {
                if(z[a]>z[a>>1])
                {
                    swap(z[a],z[a>>1]);
                    a=a>>1;
                }
                else
                    break;
            }
        }
        void shift_down(int a)
        {
            while((a<<1)<=Size)
            {
                int b=a<<1;
                if(b<Size&&z[b]<z[b+1])
                    b++;
                if(z[a]<z[b])
                {
                    swap(z[a],z[b]);
                    a=b;
                }
                else
                    break;
            }
        }
        int top()
        {
            return z[1];
        }
        void pop()
        {
            swap(z[1],z[Size]);
            Size--;
            shift_down(1);
        }
        void push(int a)
        {
            z[++Size]=a;
            shift_up(Size);
        }
    };
    bool cmp(cow a,cow b)
    {
        return a.sc<b.sc;
    }
    
    int main()
    {
        int n,c,f;
        scanf("%d%d%d",&n,&c,&f);
        for(int i=1;i<=c;i++)
            scanf("%d%d",&x[i].sc,&x[i].co);
        sort(x+1,x+c+1,cmp);
        node Q;
        Q.clear();
        int sum=0;
    
        for(int i=1;i<=n/2;i++)
        {
             Q.push(x[i].co);
             sum+=x[i].co;
        }
        for(int i=n/2+1;i<=c-n/2;i++)
        {
            x[i].l=sum;
            int q=Q.top();
            int p=x[i].co;
            if(p<q)
            {
                Q.pop();
                sum=sum+p-q;
                Q.push(p);
            }
        }
        Q.clear();
        sum=0;
        for(int i=c;i>c-n/2;i--)
        {
             Q.push(x[i].co);
             sum+=x[i].co;
        }
        for(int i=c-n/2;i>=n/2+1;i--)
        {
            x[i].r=sum;
            int q=Q.top();
            int p=x[i].co;
            if(p<q)
            {
                Q.pop();
                sum=sum+p-q;
                Q.push(p);
            }
        }
        int i;
        for(i=c-n/2;i>=n/2+1;i--)
            if(x[i].co+x[i].l+x[i].r<=f)
                break;
        if(i>=n/2+1)
            printf("%d
    ",x[i].sc);
        else
            printf("-1
    ");
    
        return 0;
    }
  • 相关阅读:
    vi简单操作说明
    start django server
    计划
    在C#程序中使用ocx的方法
    在存储过程中使用另一个存储过程返回的查询结果集
    Java位操作大全(通用于C语言)
    对面象对象概念的理解、解释
    读书笔记 UltraGrid(14)
    Svcutil使用点滴
    水晶报表使用push模式(2)
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6149104.html
Copyright © 2011-2022 走看看