AC算法社 寒假集训二

STL 组件

STL 是 C++ 标准程序库的核心。STL 内的所有组件都由模板构成,其元素可以是任意型别。程序员通过选用恰当的群集类别调用其成员函数和算法中的数据即可。
容器
容器即用来存储并管理某类对象的集合。每一种容器都有其优点和缺点。为满足程序的各种需求,STL 准备了多种容器类型,容器可以是 arrays 或是 linked lists,或者每个元素有特别的键值。
迭代器
迭代器用于在一个对象群集的元素上进行遍历动作。对象群集可能是容器,也可能是容器的一部分。
迭代器的主要用途是为容器提供一组很小的公共接口。利用这个接口,某项操作可以行进至群集内的下一个元素。每种容器都提供了各自的迭代器。迭代器了解该容器的内部结构,所以能够正确行进。迭代器的接口和一般指针类似。
算法
算法用来处理群集内的元素,可以出于不同目的搜寻、排序、修改、使用那些元素。所有容器的迭代器都提供一致的接口,通过迭代器的协助,算法程序可以用于任意容器。
STL 的一个特性是将数据和操作分离。数据由容器类别加以管理,操作则由可定制的算法定义。迭代器在两者之间充当“粘合剂”,以使算法可以和容器交互运作。
STL 的另一个特性即组件可以针对任意型别运作。“标准模板库”这一名称即表示“可接受任意型别”的模板,并且这些型别均可执行必要操作。
在 STL 中,容器又分为序列式容器和关联式容器两大类,而迭代器的功能主要是遍历容器内全部或部分元素的对象。迭代器可划分为 5 种类属,这 5 种类属归属两种类型:双向迭代器和随机存取迭代器。
SIL 中提供的算法包括搜寻、排序、复制、重新排序、修改、数值运算等。

主要介绍:

对于算法比赛,STL库就像一个工具,现成的数据结构,我们拿来就用,先弄懂怎么用,原理可以以后在研究。
为什么要用STL库:方便

几种常见的容器:

vector:灵活的 “数组”

1.向量尾部插入/删除元素:

array.push_back(a); //尾部插入数字a
array.pop_back(); //删除向量的最后一个元素

2.使用下标访问元素:

array[0],array[1]......array[n]

3.插入元素:

array.insert(array.begin()+i,a); //在第i+1个元素前面插入a;

4.删除元素:

array.erase(array.begin()+2); //删除第3个元素
array.erase(array.begin()+i,array.end()+j); //删除区间[i,j-1],区间从0开始

5.向量大小: array.size();

6.清空: array.clear();

7.判空:array.size();

8.输出方式:

vector<int> v; 
int n = v.size();   

//方法一(下标方式) 
for(int i=0;i<n;i++)    
{    
   cout<<v[i]<<" ";    
}    
cout<<endl;   
   
//方法二(auto方式)    
for(auto x:v)    
{    
     cout<<x<<" "
}    
cout<<endl;    
   
//方法三(遍历器方式)输出某一指定的数值时不方便
for(vector<int>::iterator it = v.begin();it!=v.end();it++)    
{    
    cout<<*it<<" ";    
}    
cout<<endl;    

9.使用reverse将元素翻转:

reverse(array.begin(),array.end()); //将元素翻转,即逆序排列

10.使用sort排序:
默认升序:sort(array.begin(),array.end());
浅谈一下sort~
奖学金评选
拼一个最大数

set: 有序的集合容器

set 是一个内部自动有序且不含重复元素的容器。
set 最主要的作用就是自动去重并按升序排序,适用于需要去重但是又不方便直接开数组的情况。

set常用操作

set<int> s;     //以int型为例 默认按键值升序
set<int,greater<int>> p;  //降序排列 
int x;
s.insert(x);	//将x插入q中
s.erase(x);		//删除q中的x元素,返回0或1,0表示set中不存在x
s.clear();		//清空q
s.empty();		//判断q是否为空,若是返回1,否则返回0
s.size();		//返回q中元素的个数
s.find(x);		//在q中查找x,返回x的迭代器,若x不存在,则返回指向q尾部的迭代器即 q.end()
s.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素
s.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素
s.rend();		  //返回第一个元素的的前一个元素迭代器
s.begin();		  //返回指向q中第一个元素的迭代器
s.end();		 //返回指向q最后一个元素下一个位置的迭代器
s.rbegin();		 //返回最后一个元素

set多元素应用(结构体)

struct node{
	int a,b;
	bool operator< (const node W)const
	{
		return a>W.a;  //按a的值升序 
	}
}s;

练习:
基础
产生冠军
理解题意,掌握一条铁律,一个人只能存在与唯一队伍中,即非胜即败
代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	string a,b;
	while(cin>>n && n){
		set<string> A,B;
		for(int i=0;i<n;i++){
			cin>>a>>b;
			if(B.find(a)!=B.end()){
				A.erase(b);
				B.insert(b);
			}else{
				A.insert(a);
				A.erase(b);
				B.insert(b);
			}
		}
		if(A.size()==1) cout<<"Yes\n";
		else cout<<"No\n";
	}
	return 0;
}

PTA甲级
题意

multiset :允许重复的set

queue :队列容器,先进先出

常用操作

push()  //push(x) 将 x 进行入队,时间复杂度为 O(1)
front()back()  //push(x) 将 x 进行入队,时间复杂度为 O(1)
pop()  //pop()令队首元素出队,时间复杂度为 O(1)
empty()  //empty() 检测 queue 是否为空,返回 true 则空,返回 false 则非空 。时间复杂度为 O(1)
size()    //size() 返回 queue 中元素的个数,时间复杂度为 O(1)

在使用pop()和front()函数之前必须先使用empty()函数判断队列是否为空!

海港

#include <bits/stdc++.h>
using namespace std;
int a[300010],n,n1,x,t1,cnt;
struct node
{
    int t;//time
    int c;//country
};
int main()
{
    queue<node> q;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&t1,&n1);
        for(int i=0;i<n1;i++)
        {
            scanf("%d",&x);
            q.push({t1,x});
            if(a[x]==0)cnt++;
            a[x]++;
        }
        while(t1-q.front().t>=86400&&!q.empty())//!q.empty()很重要
        {
            a[q.front().c]--;
            if(a[q.front().c]==0)cnt--;
            q.pop();
        }
        printf("%d\n",cnt);
    }
    return 0;
}

后面bfs,广度优先搜索等等,都会有用到

stack :栈容器,后进后出

stack
常用操作

push()
pop()
top()
empty()
size()

在使用pop()和top()函数之前必须先使用empty()函数判断栈是否为空
练习:
括号匹配
出栈序列的合法性

deque :双端队列容器,两头都能出

常用操作
在这里插入图片描述

priority_queue :一种按值排序的队列容器(默认大根堆/降序)。

常用操作

empty( )  //判断一个队列是否为空
pop( )  //删除队顶元素
push( )  //加入一个元素
size( )  //返回优先队列中拥有的元素个数
top( )  //返回优先队列的队顶元素
//升序队列
priority_queue <int,vector<int>,greater<int> > q;

pair的比较,先比较第一个元素,第一个相等比较第二个

priority_queue<pair<int, int> > a;
    a.push(make_pair(1,2));
    a.push(make_pair(1,3));
    a.push(make_pair(2,5));
    while (!a.empty()) {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }

对于自定义类型

//方法1
struct tmp1 //运算符重载<
{
    int x;
    tmp1(int a) {x = a;}
    bool operator<(const tmp1& a) const
    {
        return x < a.x; //大顶堆
    }
};
//方法2
struct tmp2 //重写仿函数
{
    bool operator() (tmp1 a, tmp1 b) 
    {
        return a.x < b.x; //大顶堆
    }
};
priority_queue<tmp1, vector<tmp1>, tmp2> f;

map:关联数组容器,映射。

map是STL的一个关联容器,它提供一对一的hash。
第一个可以称为关键字(key),每个关键字只能在map中出现一次;
第二个可能称为该关键字的值(value);
常用操作

   begin()         返回指向map头部的迭代器
   clear()        删除所有元素
   empty()         如果map为空则返回true
   end()           返回指向map末尾的迭代器
   erase()         删除一个元素
   find()          查找一个元素
   insert()        插入元素
   size()          返回map中元素的个数
   lower_bound()   返回键值>=给定元素的第一个位置
   upper_bound()    返回键值>给定元素的第一个位置

练习:
PTA

multimap :允许重复的map。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值