codevs 1285 二叉查找树STL基本用法

C++STL库的set就是一个二叉查找树,并且支持结构体。

在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较。

 

set经常会用到迭代器,这里说明一下迭代器:可以类似的把它看成是一个“下标”,它是指向set集合中的某个元素的指针,它用来遍历这个集合。

 

头文件

#include<set>

#include<iterator> //set 经常会使用到迭代器,因此需要迭代器的头文件

 

定义二叉查找树:

set<数据类型> 名称:

multiset<数据类型> 名称; //multiset 是可重集合,set是不可重集合。

 

定义迭代器:

set<数据类型>::iterator 名称;

multiset<数据类型>::iterator 名称;

 

一些常用的操作:

插入一个元素v:

S.insert(v); //S是定义过的集合,下面相同

 

集合的大小:

S.size();

 

集合为空吗:

S.empty();

 

集合中最小的元素:

S.begin(); //这是一个指向那个位置的指针,若要值则要在前面加上*

*S.begin(); //前面加*就是那个位置的值

 

集合中最大的元素:

S.end();  //解释同上

*S.end();

 

集合中>=v的第一个元素:

it=S.lower_bound(v) //it是定义过的迭代器,注意集合不为空

 

集合中>v的第一个元素:

it=S.upper_bound(v)//要注意存在这样的>v的数,否则会溢出

 

迭代器操作:(a,b是定义过的迭代器)

a=b;   //赋值操作

a++;  //增加一位,即指向比这个元素a大一点点的那个元素

a--;    //减少一位,即指向比这个元素a小一点点的那个元素

 

删除迭代器it指向的那个元素:

S.erase(it);  

 

删除数字为v的那个元素(注意用在multiset时会删除所有v的元素):

S.erase(v);

 

从小到大输出所有集合中的元素:

copy(S.begin(),S.end(),ostream_iterator<数据类型>(cout," "));  

 

以上就是一些常用的指令,下面看一道模板题。

题目: codevs 1285 宠物收养所

链接:http://codevs.cn/problem/1285/

 

个人觉得这道题的算法还是很巧妙的。

题目中说:同一时间呆在收养所中的,要么全是宠物,要么全是领养者。这就意味着不可能有人和宠物同时存在的情况,也就是有一个宠物那一个人必须领走。如果宠物少,那么就只能等在那里,等宠物来了。其实这道题中人领养宠物和宠物领养人是等价的,因此,在宠物集合为空的时候,把人当成宠物放进集合(二叉查找树)里面,就可以解决了。

 

还有一个小技巧,为了避免访问lower_bound的时候越界,可以在刚开始的时候加入正无穷和负无穷(一个允许的很大的值)两个边界,在结算的时候判断一下就可以了。还有要注意这个时候的集合为空的判断是S.size()==2。

 

附代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<set>
 4 #include<iterator>
 5 using namespace std;
 6 const int maxn=80010;
 7 const int INF=(1<<30);
 8 const int MOD=1000000;
 9 
10 int n,ans,sert;
11 set<int> S;
12 set<int>::iterator lt,rt;
13 
14 int main()
15 {
16     cin>>n;
17     S.insert(INF),S.insert(-INF);
18     for(int i=1,x,y;i<=n;i++)
19     {
20         cin>>x>>y;
21         if(2==S.size())    sert=x,S.insert(y);
22         else if(x==sert) S.insert(y);
23         else 
24         {
25             rt=S.lower_bound(y);
26             lt=rt,lt--;
27             if(y-*lt<=*rt-y && *lt!=-INF) ans=(y-*lt+ans)%MOD,S.erase(lt);
28             else ans=(*rt-y+ans)%MOD,S.erase(rt);
29         }
30     }
31     cout<<ans<<endl;
32     return 0;
33 } 

 

posted on 2017-01-07 16:35  Frank的成长之路  阅读(...)  评论(...编辑  收藏

导航

统计