题目出处
4951. 整理账本 - AcWing题库https://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;
}