STL Set 送花

版权声明:未经本蒟蒻同意,请勿转载本蒻博客 https://blog.csdn.net/wddwjlss/article/details/83145975

题意:三种操作
1.添加一朵美丽值为W,价格为C的花。
2.删除最便宜的一朵花。
3.删除最贵的一朵花。
若删除操作时没有花,则跳过删除操作。
如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。
所有操作结束后,求美丽值之和和价格之和。

这题正解是平衡树?总之用Set就过了,以下是Set的一些基本操作
1.定义一个Set:

set<int> s;

2.插入一个数 a a

s.insert(a);

3.删除一个数 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 是一个迭代器, i t *it 才是它的值。

5.查询set中最大/最小的值

*s.begin()
*s.end();

6.查询一个元素 a a 是否出现(set为1或0,multiset为出现的次数)

s.count(a);

7.查询大于(等于) a a 的第一个元素

set<int>::iterator it;
it=s.upper_bound();
it=s.lower_bound();

注意此时的 i t it 是一个迭代器, i t *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;
}

猜你喜欢

转载自blog.csdn.net/wddwjlss/article/details/83145975