AcWing(4951. 整理账本)STL

 题目出处

4951. 整理账本 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/file_system/file/content/whole/index/content/10768180/

 

账本中记录了一种产品的 n𝑛 条买卖记录。

记录分为两种,格式如下:

  • B p q,表示以 p元/件的价格,买入 q件该种商品。
  • S p q,表示以 p 元/件的价格,卖出 q件该种商品。

任何卖出记录的交易价格都高于任何买入记录的交易价格。

也就是说,不会存在卖出记录和买入记录的交易价格相同的情况。

现在,请你对账本进行整理,对所有交易价格相同的记录进行合并,使得每个交易价格只存在一条记录,新记录的交易数量等于所有参与合并的旧记录的交易数量之和。

具体来说,如果账本中有 k𝑘 条记录的交易价格为 p𝑝,它们的交易数量分别为 q1,q2,…,qk,则将它们合并为一条新记录,新记录的交易价格仍为 p𝑝,交易数量为 q1+q2+…+qk。

注意:

  • 合并为新记录后,参与合并的旧记录就从帐本中抹除了。
  • 新纪录的交易类型(买入或卖出)保持不变,即与参与合并的旧记录保持一致。
  • 不会存在卖出记录和买入记录的交易价格相同的情况。

整理完毕后,对于现有的所有记录,请你找到其中交易价格最低的 s 条卖出记录和交易价格最高的 s 条买入记录。

输入格式

第一行包含两个正整数 n,s。

接下来 n 行,每行包含一个记录,格式如题目描述。

输出格式

首先,按照交易价格从高到低的顺序,输出交易价格最低的 s条卖出记录,每行一条,格式与输入相同。如果不足 s 条,则有多少输出多少。

然后,按照交易价格从高到低的顺序,输出交易价格最高的 s条买入记录,每行一条,格式与输入相同。如果不足 s 条,则有多少输出多少。

数据范围

前 4个测试点满足 1≤n≤6。
所有测试点满足 1≤n≤1000,1≤s≤50,0≤p≤10e5,1≤𝑞≤10e4。

输入样例:
6 2
B 10 3
S 50 2
S 40 1
S 50 6
B 20 4
B 25 10
输出样例:
S 50 8
S 40 1
B 25 10
B 20 4

 题意:给出几组数据,排序后输出;

用到了数据结构里面的STL,STL是非常重要的在我们学习算法的过程中,是一座大山等着我们跨过;

这一题,输出S或者B有两种不同的效果,显而易见要用到map,其中map內部的实现自建一颗红黑树,有排序功能,所以map是这题的关键解题点。我们要会map的排序,自定义排序和遍历等基础知识。题目中说到按照交易价格从高到低的顺序,输出交易价格最低的 s条卖出记录,每行一条,格式与输入相同。如果不足 s 条,则有多少输出多少按照交易价格从高到低的顺序,输出交易价格最高的 s条买入记录,每行一条,格式与输入相同。如果不足 s 条,则有多少输出多少

我们可以知道要开两个map其中一个map<int,int,greater<int>>mp降序写map,另一个是要在降序的基础上找到最小的一部分,所以我们可以定义一个map<int,int>mp1后续再倒序输出就可以了。为什么我要这样来写呢?因为要想输出map其中一部分还是比较麻烦的,我们可以用vector定义一个vector<pair<int,int> >v来存下两个值,利用到了pair的特性,后续我们直接给vector倒着遍历输出就ok了,就可以得到S部分的输出了B部分我们直接将值降序存入map里面,后续用auto遍历一遍输出就可以得到B部分了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main ()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	map<int,int,greater<int> >mp1;//降序mp
	map<int,int>mp;//升序map
	vector< pair<int,int> >v;//STL的知识
	int n,s;cin>>n>>s;
	for (int i=0;i<n;i++)
	{
		char ch;int x,y;
		cin>>ch>>x>>y;
		if (ch=='S')
		{
			mp[x]+=y;
		}
		else 
		{
			mp1[x]+=y;
		}
	}int k=0,k1=0;
	for (auto it : mp)
	{
		v.push_back({it.first,it.second});
		k1++;
		if (k1==s)break;
	}//遍历map将值存入vector数组里面


	reverse(v.begin(),v.end());//将vector数组反转过来
	for(auto i : v)
	{
		cout<<"S"<<' ';
		cout<<i.first<<' '<<i.second<<'\n';
	}//vector反转过来后直接遍历输出

	for (auto it:mp1)
	{
		
		cout<<"B"<<' ';
		cout<<it.first<<' '<<it.second<<'\n';
		k++;
		if (k==s)break;
		
	}//这个就很简单了,直接输出
	return 0;
}

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值