1. 程式人生 > >STL Set 送花

STL Set 送花

題意:三種操作
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;
}