算法竞赛基础(常用函数、数据结构)

文章大纲(需要跳转目录,在右下角)

  1. 快速重置数组的值
  2. 使用c++的排序
  3. 优先队列
  4. vector的使用方法
  5. 几种重要的函数
  6. 巧用输入输出

快速重置数组的值

(1) memset(recode,0, sizeof(recode));//重置记忆化数组
(2) memset(recode,-1, sizeof(recode));//重置记忆化数组

只有使用-1和0可以快速重置数组,因为-1,和0 的二进制(补码)分别全为1,全为0,这样在重置的时候,只要把整个数组的二进制区域全部设置成1或者0即可

使用c++的排序

需要使用到sort(开始,结束,比较规则)
比较规则为一个返回bool值到自定义函数

//
// Created by Leo Lee on 2019/4/20.
//

//学习使用c++ 的sort

#include <iostream>
#include <algorithm>//必须包含的头文件
using namespace std;
struct work{
    int level;//工作的等级
    int longtime;//工作的时长
};
work w[5];
void output();
bool cmp(work w1,work w2);
int main(){
    for(int i = 0;i<5;i++){
        cin>>w[i].level>>w[i].longtime;
    }
    output();//输入数据
    sort(w,w+5,cmp);
    output();//改变顺序后的数据
    return 0;
}

void output(){
    for(int i =0;i<5;i++){
        cout<<w[i].level<<":"<<w[i].longtime<<" ";
    }
    cout<<endl;
}
bool cmp(work w1,work w2){
    if(w1.level != w2.level) //首先按照level排序,level一样则按照longtime排序
        return w1.level<w2.level;//表示按左边小,右边大的次序排序
    else
        return w1.longtime<w2.longtime;
}

测试:

1 3
1 2
3 3
2 5
3 2
1:3 1:2 3:3 2:5 3:2 
1:2 1:3 2:5 3:2 3:3 

优先队列

优先队列使用堆来实现的,插入和删除的复杂度很低

优先队列的基础操作
基本操作:

empty()      如果队列为空,则返回真

pop()    删除对顶元素,删除第一个元素

push()        加入一个元素

size()      返回优先队列中拥有的元素个数

top()     返回优先队列对顶元素,返回优先队列中有最高优先级的元素
元素是结构体的优先队列。

需要定义结构体的同时,定义结构体之间的比较规则

#include <iostream>
#include <algorithm>
#include <queue> // 必须包含此文件
using namespace std;
struct work{
    int level;
    int longtime;
    bool operator < (work w2) const{
        if (level != w2.level)
            return level>w2.level; // 和普通的比较函数是相反的
        else
            return longtime>w2.longtime;
    }
};
int main(){
    priority_queue<work> Q;
    int tmp1,tmp2;
    for(int i = 0;i<5;i++){
        cin>>tmp1>>tmp2;
        Q.push(work{tmp1,tmp2});
    }
    work tmpw;
    putchar('\n');
    while(Q.size()>0){
        tmpw = Q.top();
        cout<<tmpw.level<<" "<<tmpw.longtime<<endl;
        Q.pop();
    }

    return 0;
}

元素是基础元素的优先队列
//定义一个优先队列
priority_queue<int,vector<int>, greater<int> > q;    //通过操作,按照元素从小到大的
顺序出队
//自定义优先级比较函数

使用STL vector

vector 的初始化
    (1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。2)vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为13)vector<int> a(b); //用b向量来创建a向量,整体复制性赋值4)vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素5int b[7]={1,2,3,4,5,9,8};
        vector<int> a(b,b+7); //从数组中获得初值

vector对象的几个重要操作
1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a2)a.assign(4,2); //是a只含4个元素,且每个元素为23)a.back(); //返回a的最后一个元素4)a.front(); //返回a的第一个元素5)a[i]; //返回a的第i个元素,当且仅当a[i]存在2013-12-076)a.clear(); //清空a中的元素7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false8)a.pop_back(); //删除a向量的最后一个元素9)a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+         3(不包括它)10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为511)a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,412)a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为513)a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8         ,插入元素后为1,4,5,9,2,3,4,5,9,814)a.size(); //返回a中元素的个数;15)a.capacity(); //返回a在内存中总共可以容纳的元素个数16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机17)a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为218)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才         显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能) 19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<

几种重要的函数

1sort(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列2reverse(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,13copy(a.begin(),a.end(),b.begin()+1); //把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开        始复制,覆盖掉原有元素4find(a.begin(),a.end(),10); //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置

巧用输入输出

处理回车符(去掉多余的空白符的输入方法)

有时候会因为读入字符,而不得不处理掉回车的问题,在此可以使用下面的方式读入

scanf(" %c", &ch)

只是加了一个空格,但是这个空格可以吸收掉想要读取那个字符前面的所有空白符(空格、tab 、回车符)

时间复杂度(渐近时间复杂度的严格定义,NP问题,时间复杂度的分析方法,主定理)   排序算法(平方排序算法的应用,Shell排序,快速排序,归并排序,时间复杂度下界,三种线性时间排  序,外部排序)   数论(整除,集合论,关系,素数,进位制,辗转相除,扩展的辗转相除,同余运算,解线性同余方程,中国剩余定理) 指针(链表,搜索判重,邻接表,开散列,二叉树的表示,多叉树的表示) 按位运算(and,or,xor,shl,shr,一些应用) 图论(图论模型的建立,平面图,欧拉公式与五色定理,求强连通分量,求割点和桥,欧拉回路,AOV问题,AOE问题,最小生成树的三种算法,最短路的三种算法,标号法,差分约束系统,验证二分图,Konig定理,匈牙利算法,KM算法,稳定婚姻系统,最大流算法,最小割最大流定理,最小费用最大流算法) 计算几何(平面解几及其应用,向量,点积及其应用,叉积及其应用,半平面相交,求点集的凸包,最近点对问题,凸多边形的交,离散化与扫描) 数据结构(广度优先搜索,验证括号匹配,表达式计算,递归的编译,Hash表,分段Hash,并查集,Tarjan算法,二叉堆,左偏树,二斜堆,二项堆,二叉查找树,红黑树,AVL平衡树,Treap,Splay,静态二叉查找树,2-d树,线段树,二维线段树,矩形树,Trie树,块状链表) 组合数学(排列与组合,鸽笼原理,容斥原理,递推,Fibonacci数列,Catalan数列,Stirling数,差分序列,生成函数,置换,Polya原理) 概率论(简单概率,条件概率,Bayes定理,期望值) 矩阵(矩阵的概念和运算,二分求解线性递推方程,多米诺骨牌棋盘覆盖方案数,高斯消元) 字符串处理(KMP,后缀树,有限状态自动机,Huffman编码,简单密码学) 动态规划(单调队列,凸完全单调性,树型动规,多叉转二叉,状态压缩类动规,四边形不等式) 博奕论(Nim取子游戏,博弈树,Shannon开关游戏) 搜索(A*,ID,IDA*,随机调整,遗传算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值