Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

用堆维护前k小的数,左右扫描预处理,枚举中位数的位置

Posted by 13091258 at 2014-06-09 09:23:12 on Problem 2010
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<fstream>
#include<string>
#include<map>
#include<set>
#include<utility>
#include<queue>
#include<stack>
#include<ctime>
#include<ctype.h>
#include<iomanip>//输出保留精度 
#define INF (1<<28)
#define EPS 1e-6
#define PI acos(-1)
#define lowbit(a) ((a) & (-(a)))
#define min(a,b) ((a)<(b) ? (a):(b))
#define max(a,b) ((a)>(b) ? (a):(b))
#define abs(a) ((a)>0?(a):-(a))
#define swp(a,b) {int tem=a; a=b; b=tem;}
#define SET(a,b) memset(a,b,sizeof(a))
using namespace std;
ifstream fin("C-large-practice.in");
//ofstream fout("C-small-practice.out");
typedef unsigned long ull;//2^63 
typedef long long ll;//2^62 
typedef pair<int, int> P;
const int MAX_N=5000;
const int MAX_M=2100;
const int MAX_V=1000;
const int MAX_E=1000;
const int M=1000000;

int n,m,fsum;
struct nod
{
    int c,f;
    bool operator<(const nod& x) const
    {
        return f<x.f;
    }
}a[100000];
bool cmp(const nod& x,const nod& y)
{
    return x.c<y.c;
}

int minl[100000],minr[100000];
//minl[i]表示i左边前n/2小的数的和
//minr[i]表示i右边前n/2小的数的和
priority_queue<nod> ql,qr;//大顶堆,维护前n/2个最小的数
void solve()
{
    int ans=-1,sum1=0,sum2=0;
    sort(a,a+m,cmp);
    for(int i=0;i<m;i++)
    {
        if(i<n/2) 
        {
            ql.push(a[i]); sum1+=a[i].f;
            continue;
        }
        minl[i]=sum1;
        if(a[i].f>=ql.top().f) continue;
        sum1-=ql.top().f; 
        ql.pop();
        sum1+=a[i].f;
        ql.push(a[i]);
    }

    for(int i=m-1;i>=0;i--)
    {
        if(i>m-1-n/2)
        {
            qr.push(a[i]); sum2+=a[i].f;
            continue;
        }
        minr[i]=sum2;
        if(a[i].f>=qr.top().f) continue;
        sum2-=qr.top().f;
        qr.pop();
        sum2+=a[i].f;
        qr.push(a[i]);
    }

	//枚举中位数的位置,在其左右各选n/2个最小的数
    for(int i=m-1-n/2;i>=n/2;i--)
        if(minl[i]+minr[i]+a[i].f<=fsum)
        {
            ans=a[i].c; break;
        }    
    cout<<ans<<endl;
} 

int main()
{ 
    cin>>n>>m>>fsum;
    for(int i=0;i<m;i++) scanf("%d%d",&a[i].c,&a[i].f);
   
    solve();
    
    system("pause");
    return 0;
} 

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator