Fork me on GitHub

2014 Super Training #6 H Edward's Cola Plan --排序+二分

原题: ZOJ 3676  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3676

题意:给每个朋友一瓶可乐,可乐有普通和高级两种,每个朋友只能喝一瓶可乐,喝普通可乐的朋友会给你P个瓶盖,喝高级可乐的朋友会给你Q个瓶盖。问最多能得到多少个瓶盖。瓶盖可以借。

解法:因为瓶盖可以借任意多个,所以按Q-P排序即可,二分临界点Q-P=0的点,即Q-P<m的让他和普通可乐,Q-P>m的喝高级可乐,Q-P=m的无所谓喝什么。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define N 100007

struct node
{
    int P,Q;
    int dif;
}p[N];

int SP[N],SQ[N];

int cmp(node ka,node kb)
{
    return ka.dif < kb.dif;
}

int main()
{
    int n,m,k;
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        SP[0] = SQ[0] = 0;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i].P,&p[i].Q);
            p[i].dif = p[i].Q-p[i].P;
        }
        sort(p+1,p+n+1,cmp);
        for(i=1;i<=n;i++)
        {
            SP[i] = SP[i-1]+p[i].P;
            SQ[i] = SQ[i-1]+p[i].Q;
        }
        for(i=0;i<m;i++)
        {
            scanf("%d",&k);
            int low = 1;
            int high = n;
            int res = -1;
            while(low <= high)
            {
                int mid = (low+high)/2;
                if(p[mid].dif < k)
                    low = mid + 1;
                else
                {
                    res = mid;
                    high = mid - 1;
                }
            }
            if(res == -1)      //如果全小于k,则全喝普通的
                printf("%d\n",SP[n]);
            else
                printf("%d\n",SP[res-1]+SQ[n]-SQ[res-1]-(n-res+1)*k);
        }
    }
    return 0;
}
View Code

 

posted @ 2014-07-11 20:07  whatbeg  阅读(261)  评论(0编辑  收藏  举报