poj-2010 Moo University - Financial Aid

版权声明:最后一年,加油~ https://blog.csdn.net/zzti_xiaowei/article/details/81913062

[题目链接]

思路:一开始就想到用二分答案,写着写着一直T,没有对堆进行预处理。改之,由于一个小bug,一直WA。然后AC之后,讨论区看一下,此题数据较弱,好多二分中位数位置k,用堆找出前n/2和后n/2的最小和与总金额f进行比较,从而l++或者r–的做法是错误的,这样不满足单调性,无法二分!

  • 数据:
    3 5 3
    4 10
    5 10
    6 1
    7 1
    8 1

正确做法:直接从后向前枚举中位数,符合即为最优!

代码:

//二分枚举中位数(其实是不对的)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int Max_n=1e5+10;

int n,c,f;
struct cow{
    int a,b;
    bool operator<(const cow &c)const {
        return a<c.a;
    }
}co[Max_n];
int p[Max_n],q[Max_n]; //堆的预处理 

bool jud(int k){
    if(p[k-1]+q[k+1]+co[k].b<=f)return true;
    return false;
}

int main()
{
    scanf("%d%d%d",&n,&c,&f);
    for(int i=0;i<c;i++)scanf("%d%d",&co[i].a,&co[i].b);
    sort(co,co+c);

    int t=n/2,sum=0;
    if(n==1){ //n==1特判 (不加竟然AC) 
        int i=c-1;
        for(;i>=0;i--){
            if(co[i].b<=f){
                printf("%d\n",co[i].a);
                break; 
            }
        }
        if(i<0)printf("-1\n");
        return 0; 
    }
    priority_queue<int>que;
    sum=0;
    for(int i=0;i<c;i++){
        que.push(co[i].b);
        sum+=co[i].b;
        if(i==t-1)p[i]=sum;
        if(i>t-1){
            sum-=que.top();
            p[i]=sum;
            que.pop();
        }
    }
    sum=0;
    for(int i=c-1;i>=0;i--){
        que.push(co[i].b);
        sum+=co[i].b;
        if(i==c-t)q[i]=sum;
        if(i<c-t){
            sum-=que.top();
            q[i]=sum;
            que.pop();
        }
    }

    int l=t,r=c-t-1,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(jud(mid))l++;
        else r--;       
    }
    if(r<t)printf("-1\n");
    else printf("%d\n",co[r].a);    
    return 0;
}
// 直接枚举中位数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int Max_n=1e5+10;

int n,c,f;
struct cow{
    int a,b;
    bool operator<(const cow &c)const {
        return a<c.a;
    }
}co[Max_n];
int p[Max_n],q[Max_n]; //堆的预处理 

bool jud(int k){
    if(p[k-1]+q[k+1]+co[k].b<=f)return true;
    return false;
}

int main()
{
    scanf("%d%d%d",&n,&c,&f);
    for(int i=0;i<c;i++)scanf("%d%d",&co[i].a,&co[i].b);
    sort(co,co+c);

    int t=n/2,sum=0;
    if(n==1){ //n==1特判 (不加竟然AC) 
        int i=c-1;
        for(;i>=0;i--){
            if(co[i].b<=f){
                printf("%d\n",co[i].a);
                break; 
            }
        }
        if(i<0)printf("-1\n");
        return 0; 
    }
    priority_queue<int>que;
    sum=0;
    for(int i=0;i<c;i++){
        que.push(co[i].b);
        sum+=co[i].b;
        if(i==t-1)p[i]=sum;
        if(i>t-1){
            sum-=que.top();
            p[i]=sum;
            que.pop();
        }
    }
    sum=0;
    for(int i=c-1;i>=0;i--){
        que.push(co[i].b);
        sum+=co[i].b;
        if(i==c-t)q[i]=sum;
        if(i<c-t){
            sum-=que.top();
            q[i]=sum;
            que.pop();
        }
    }
    int i;
    for(i=c-t-1;i>=t;i--){
        if(jud(i)){
            printf("%d\n",co[i].a);
            break;
        }
    }
    if(i<t)printf("-1\n");  
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zzti_xiaowei/article/details/81913062