笔记1(sort函数、前缀和、差分、二分、队列)

文章介绍了C++中sort函数的使用,包括快速排序的时间复杂度和自定义排序方式。一维和二维前缀和的概念及生成方法被详细阐述,用于求解区间元素之和。一维差分数组的构建和应用也在文中提及。此外,文章讨论了二分查找算法及其在不同排序情况下的变体。队列的模拟与STL实现以及map容器的使用也被涵盖,包括相关操作和功能。
摘要由CSDN通过智能技术生成

1、sort()函数

==sort()==函数类似于快速排序,时间复杂度为nlog2n

头文件:#include<algorithm>

sort(begin, end, cmp) 其中begin是指向待排序的数组的第一个元素指针,end是最后一个元素的下一个位置的指针,cmp参数为排序准则。cmp默认是按照升序排序,也可以改变参数,greater<数据类型>() //从大到小排序 less<数据类型>() //从小到大;也可以自定义排序标准。自定义一个函数,里面写排序标准,然后放到cmp位置上。还可以对结构体进行排序,也是自定义以下排序标准就好了。

2、一维前缀和

构造前缀和数组。

生成前缀和:for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]; (注意从1开始)

求 l,r 中所有元素的和。

s[l] = a1 + a2 + … + al

s[r] = a1+ a2 + … + ar

s[r]-s[l] = a(l+1) + a(l+2) + … + ar 会发现少了一个 al,所以应该写成 s[r]-s[l-1]
在这里插入图片描述

3、二维前缀和

构造前缀和数组。
在这里插入图片描述
在这里插入图片描述
在写代码的时候,会出现一个奇怪的问题,就是如果把数组a和s定义在main函数里面,会发生错误,且没有提示,暂时不知道是什么原因,就算写成 a[N][N]={0}和s[N][N]={0}也不可以,上网一查估计是因为如果将其定义在main函数里面的话,初始值是由编译器决定的,不一定为0,且对于a[N][N]={0}这样的语句,它的定义是不明确的。

如果把数组设置为全局变量,一定是会被初始化为0的。
编译器:Dev-C++ 5.11

#include<iostream>
using namespace std;
//const int N=1010;      //也可以 
#define N 1010
int a[N][N];
int s[N][N];
int main()
{
    int n,m,q;
//    int a[N][N]={0},s[N][N]={0};   //不可以这样子写 
    cin>>n>>m>>q;
    for(int i=1; i<=n; i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
            
    for(int i=1; i<=n;i++){
        for(int j=1;j<=m;j++){
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];//生成前缀和** 
        }
    }
    while(q--)
    {
        int x1,x2,y1,y2;
        cin>>x1>>y1>>x2>>y2;
        cout<<s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]<<endl;
    }
    return 0;
}

给出参考数据和答案:

输入:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出:

17
27
21

在这里插入图片描述
在这里插入图片描述

4、一维差分

构造差分数组。

原数组为 a1…an,构造数组b使得 bi 的前缀和为 ai 。如 ai = b1 + b2 + b3 +…+ bi ;

b1 = a2 - a1;

b2 = a3 - a2;

b3 = a4 - a3;

b4 = a5 - a4;

对 [ l , r ]这个范围的 ai 都加上 c 的做法:

让 b[l]+c 然后再 b[r+1]-c ;

原因:
在这里插入图片描述

5、二维差分

构造差分数组。
在这里插入图片描述
在这里插入图片描述

6、二分算法

需要注意的是,数值本身是有序的;返回的是指针。可以用 lower_bound(a, a+5, 5) - a; 的方法找到下标值。容器也是一样的,vector、set。

在小到大的排序中:

1、 lower_bound(起始地址,结束地址,要查找的数值key) 函数:返回第一个大于等于key值位置

2、upper_bound(起始地址,结束地址,要查找的数值key) 函数:返回第一个大于key值位置

在大到小的排序中:

3、lower_bound(begin, end, key, greater() )函数:找第一个小于等于key值的位置。

4、upper_bound(begin, end, key, greater() ) 函数:找第一个小于key值的位置。

上述四个函数,如果找不到的话,就返回 end末位置

注意:一定要按照排序顺序来使用这四个函数,如果是在非递减的数组中,不能使用3和4的函数,会找不到的。
在这里插入图片描述
在这里插入图片描述
binary_search(起始地址,结束地址,要查找的数值key)函数:查找key是否存在。返回布尔类型。true/false。

7、队列

例题acw:132.小组队列
可以用数组模拟队列。
int q[10000] , f = 0 , r = 1 ; //数组模拟队列,f为队头,r为队尾的下一个位置。

使用stl封装好的队列:

头文件: <queue>

    queue<int> q;        //定义int队列 
    q.push();            //入队 
    q.pop();            //出队 
    q.front();            //返回队头元素 
    q.back();            //返回队尾元素
    q.size();            //返回队列的大小 
    q.empty();             //判断队列是否为空,是返回1,不是返回0 

注意:pop、push函数是void类型的,empty函数是bool类型的,front、back返回的都是指针类型的。
优先队列、单调队列、双端队列。

8、map

例题:P1918.保龄球
map容器是一个键值对key-value的映射。
头文件:#include <map>

#include<map> 
 //初始化格式:map<key_type, value_type> mp;
 map<int, bool> mp; 

mp.size();		//元素个数 
mp.empty();		//判断是否为空 
mp.clear();		//清空map容器 
mp.begin();		//首选代器 
mp.end();		//尾选代器 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值