题意:三种操作
1.添加一朵美丽值为W,价格为C的花。
2.删除最便宜的一朵花。
3.删除最贵的一朵花。
若删除操作时没有花,则跳过删除操作。
如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。
所有操作结束后,求美丽值之和和价格之和。
这题正解是平衡树?总之用Set就过了,以下是Set的一些基本操作
1.定义一个Set:
set<int> s;
2.插入一个数 a a a
s.insert(a);
3.删除一个数 a a a
s.erase(a);
s.erase(s.begin())//删除set里最小的一个数
s.erase(--s.end())//删除set里最大的一个数
4.遍历s
for(set<int>::iterator it=s.begin();it!=s.end();it++)
注意此时的 i t it it是一个迭代器, ∗ i t *it ∗it才是它的值。
5.查询set中最大/最小的值
*s.begin()
*s.end();
6.查询一个元素 a a a是否出现(set为1或0,multiset为出现的次数)
s.count(a);
7.查询大于(等于) a a a的第一个元素
set<int>::iterator it;
it=s.upper_bound();
it=s.lower_bound();
注意此时的 i t it it是一个迭代器, ∗ i t *it ∗it才是它的值。
然后说这道题,我们开两个set,一个是int类型的,一个是pair类型的,int类型的set用来记录这个价格是否出现过,因为pair中一个值不同两个二元组就不同。另外一个set记录以价格为第一关键字,美丽值为第二关键字的pair,操作后遍历set输出即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int opt;
ll ans1,ans2;
set<pair<ll,ll> > s;
set<int> s1;
int main()
{
while(1)
{
scanf("%d",&opt);
if(opt==-1)
break;
if(opt==1)
{
ll w,c;
scanf("%lld%lld",&w,&c);
if(s1.find(c)==s1.end())
{
s1.insert(c);
s.insert(make_pair(c,w));
}
}
if(opt==2)
{
if(s.empty())
continue;
s.erase(--s.end());
s1.erase(--s1.end());
}
if(opt==3)
{
if(s.empty())
continue;
s.erase(s.begin());
s1.erase(s1.begin());
}
}
for(set<pair<ll,ll> >::iterator it=s.begin();it!=s.end();it++)
ans1+=(*it).second,ans2+=(*it).first;
cout<<ans1<<" "<<ans2;
return 0;
}