• 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 } 
  • 相关阅读:
    抓老鼠啊~亏了还是赚了?
    币值转换
    打印沙漏
    秋季学期学习总结
    PTA币值转化
    PTA作业
    秋季学习总结
    人生最重要的3个老师
    自我介绍
    vue入门(二) 让axios发送表单形式数据
  • 原文地址:https://www.cnblogs.com/frankscode/p/6259713.html
Copyright © 2020-2023  润新知