超市抽奖

来源:互联网 发布:爱奇艺软件一直唤醒 编辑:程序博客网 时间:2024/04/27 13:48

超市

market.pas/c/cpp)

【题目描述】

超市正在举行一个活动,该活动的规则如下:

想要参与的顾客会将他购物的账单放入纸箱中,账单上写有顾客的联系方式和购物的金额。每天超市关门前纸箱中金额最大、最小的两张帐单被取出,付款金额最大的顾客将获得一笔奖金,价值为取出的两张帐单的金额之差;为了不重复计算,取出的两张帐单不再放回箱子,而剩下的帐单仍保留在箱中,进行第二天的活动。

顾客很多,因此可假定:每天活动结束时,箱中至少有两张帐单以供取出。

h也参加了这次活动,他想知道整个活动期间超市付出的奖金总额是多少?

【输入数据】

第一行是一个整数n,表示活动历时的天数。

以下的n行,每行包含若干由空格分隔的非负整数。第i+1行的数表示在第i天投入箱子的账单金额。每行的第一个数是一个整数k,表示当日账单的数目。后面的k个正整数代表这k笔账单的金额。

【输出数据】

输出一个数,表示活动期间超市付出的奖金总额。

【样例输入】

5

3 1 2 3

2 1 1

4 10 5 5 1

0

1 2

【样例输出】

19

【数据范围】

s为整个活动中涉及到的账单笔数。

30%的数据满足n≤100,s≤10000。

70%的数据满足s≤10^5。

100%的数据满足1≤n≤5000,0≤k≤10^5,s≤10^6,每笔账单的金额不超过10^6。




分析:刚开始用map做的,结果编译总过不了,后来改为优先队列。

其实我们可以维护两个堆,一个大根,一个小根。每次都取出两个堆顶,判段是否已用过,然后做差即可。


参考程序:

#include<cstdio>#include<algorithm>#include<queue>using namespace std;priority_queue<int> Q1;priority_queue<int,vector<int>,greater<int> >Q2;int ok[1100000];int main(){freopen("market.in","r",stdin);freopen("market.out","w",stdout);int T,n;long long ans=0;scanf("%d",&T);while (T--){scanf("%d",&n);for (int i=1;i<=n;i++){int x;scanf("%d",&x);Q1.push(x);Q2.push(x);ok[x]++;}while (ok[Q1.top()]<=0)Q1.pop();while (ok[Q2.top()]<=0)Q2.pop();ans+=Q1.top()-Q2.top();ok[Q1.top()]--;Q1.pop();ok[Q2.top()]--;Q2.pop();}printf("%lld",ans);return 0;}


0 0
原创粉丝点击