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

 

你可能感兴趣的:(super)