【一本通测评1372】【堆】小明的账单

小明的账单

一本通测评1372:小明的账单


题目

【题目描述】
小明在一次聚会中,不慎遗失了自己的钱包,在接下来的日子,面对小明的将是一系列的补卡手续和堆积的账单… 在小明的百般恳求下,老板最终同意延缓账单的支付时间。可老板又提出,必须从目前还没有支付的所有账单中选出面额最大和最小的两张,并把他们付清。还没有支付的账单会被保留到下一天。 请你帮他计算出支付的顺序。

【输入】
第1行:一个正整数N(N≤15,000),表示小明补办银联卡总共的天数。

第2行到第N+1 行:每一行描述一天中收到的帐单。先是一个非负整数M≤100,表示当天收到的账单数,后跟M个正整数(都小于1,000,000,000),表示每张帐单的面额。

输入数据保证每天都可以支付两张帐单。

【输出】
输出共N 行,每行两个用空格分隔的整数,分别表示当天支付的面额最小和最大的支票的面额。

【输入样例】

4
3 3 6 5
2 8 2
3 7 1 7
0

【输出样例】

3 6
2 8
1 7
5 7

解题思路

暴力用大根堆和小根堆存储
但是问题是可能在大根堆中已经输出过的账单,不久后变成了小跟堆的堆顶
解决方案:记录下每个账单的编号,拿个数组标记当前账单还过没


Code

#include <bits/stdc++.h>

using namespace std;

int n, m, x, num;
bool v[1500200];
priority_queue<pair<int, int> > q, p;

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d", &m);
		for(int j = 1; j <= m; j ++) {
			scanf("%d", &x);
			q.push(make_pair(x, ++ num)), p.push(make_pair(-x, num));
		}
		while(v[q.top().second]) q.pop();
		while(v[p.top().second]) p.pop();
		printf("%d %d\n", -p.top().first, q.top().first);
		v[q.top().second] = v[p.top().second] = 1;
		q.pop(), p.pop();
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值