csp信奥赛C++标准模板库STL(11):STL常用算法详解
一、排序算法
1. sort - 快速排序
#include<algorithm>#include<vector>#include<iostream>usingnamespacestd;intmain(){vector<int>v={5,3,8,1,4};// 默认升序排序sort(v.begin(),v.end());// v = {1, 3, 4, 5, 8}// 降序排序sort(v.begin(),v.end(),greater<int>());// v = {8, 5, 4, 3, 1}// 自定义排序规则vector<pair<int,int>>pairs={{1,5},{2,3},{1,2}};sort(pairs.begin(),pairs.end(),[](constpair<int,int>&a,constpair<int,int>&b){if(a.first==b.first)returna.second<b.second;returna.first<b.first;});return0;}2. stable_sort - 稳定排序
保持相等元素的相对顺序
vector<int>v={5,2,8,2,4};stable_sort(v.begin(),v.end());// 相等的2保持原有相对顺序二、查找算法
1. find - 线性查找
vector<int>v={1,3,5,7,9};autoit=find(v.begin(),v.end(),5);if(it!=v.end()){cout<<"找到元素5,位置: "<<distance(v.begin(),it)<<endl;}2. binary_search - 二分查找(仅判断是否存在)
vector<int>v={1,3,5,7,9};// 必须先排序!sort(v.begin(),v.end());boolfound=binary_search(v.begin(),v.end(),5);if(found)cout<<"找到5"<<endl;3. lower_bound / upper_bound - 边界查找
vector<int>v={1,2,3,3,3,4,5};sort(v.begin(),v.end());// lower_bound: 第一个>=val的位置autolb=lower_bound(v.begin(),v.end(),3);// 指向第一个3// upper_bound: 第一个>val的位置autoub=upper_bound(v.begin(),v.end(),3);// 指向4// 计算某个值出现的次数intcount=ub-lb;// 3的个数为3三、计数算法
1. count - 统计特定值出现次数
vector<int>v={1,2,3,2,4,2,5};intcnt=count(v.begin(),v.end(),2);cout<<"2出现的次数: "<<cnt<<endl;// 输出32. count_if - 条件统计
vector<int>v={1,2,3,4,5,6,7,8};inteven_cnt=count_if(v.begin(),v.end(),[](intx){returnx%2==0;});cout<<"偶数个数: "<<even_cnt<<endl;// 输出4四、排列算法
1. next_permutation - 下一个排列
vector<int>v={1,2,3};do{for(intnum:v)cout<<num<<" ";cout<<endl;}while(next_permutation(v.begin(),v.end()));// 输出所有排列:123, 132, 213, 231, 312, 3212. prev_permutation - 上一个排列
vector<int>v={3,2,1};do{for(intnum:v)cout<<num<<" ";cout<<endl;}while(prev_permutation(v.begin(),v.end()));// 输出逆序排列五、其他重要算法
1. unique - 去重(需要先排序)
vector<int>v={1,2,2,3,3,3,4,5};sort(v.begin(),v.end());autolast=unique(v.begin(),v.end());v.erase(last,v.end());// v = {1, 2, 3, 4, 5}2. reverse - 反转
vector<int>v={1,2,3,4,5};reverse(v.begin(),v.end());// v = {5, 4, 3, 2, 1}3. rotate - 旋转
vector<int>v={1,2,3,4,5};// 以第3个元素为起点旋转rotate(v.begin(),v.begin()+2,v.end());// v = {3, 4, 5, 1, 2}4. max_element / min_element - 最大/最小元素
vector<int>v={3,1,4,1,5,9};automax_it=max_element(v.begin(),v.end());automin_it=min_element(v.begin(),v.end());cout<<"最大值: "<<*max_it<<endl;// 9cout<<"最小值: "<<*min_it<<endl;// 15. accumulate - 累加
#include<numeric>vector<int>v={1,2,3,4,5};intsum=accumulate(v.begin(),v.end(),0);cout<<"和: "<<sum<<endl;// 15// 也可以用于累乘intproduct=accumulate(v.begin(),v.end(),1,multiplies<int>());cout<<"乘积: "<<product<<endl;// 1206. fill - 填充
vector<int>v(5);// 5个0fill(v.begin(),v.end(),7);// v = {7, 7, 7, 7, 7}7. copy - 复制
vector<int>src={1,2,3,4,5};vector<int>dst(5);copy(src.begin(),src.end(),dst.begin());8. transform - 变换
vector<int>v1={1,2,3};vector<int>v2={4,5,6};vector<int>result(3);// 两向量相加transform(v1.begin(),v1.end(),v2.begin(),result.begin(),plus<int>());// result = {5, 7, 9}// 单个向量变换transform(v1.begin(),v1.end(),result.begin(),[](intx){returnx*x;});// result = {1, 4, 9}六、算法综合应用示例
案例1:统计满足条件的元素
#include<algorithm>#include<vector>#include<iostream>usingnamespacestd;intmain(){vector<int>scores={85,92,78,90,88,95,70};// 统计90分以上的人数inthigh_scores=count_if(scores.begin(),scores.end(),[](ints){returns>=90;});// 找到最高分automax_score=*max_element(scores.begin(),scores.end());// 排序并去掉最低分和最高分sort(scores.begin(),scores.end());scores.erase(scores.begin());// 去掉最低分scores.pop_back();// 去掉最高分// 计算平均分doubleavg=accumulate(scores.begin(),scores.end(),0.0)/scores.size();cout<<"90分以上: "<<high_scores<<"人"<<endl;cout<<"最高分: "<<max_score<<endl;cout<<"平均分(去掉最高最低): "<<avg<<endl;return0;}案例2:排列组合问题
#include<algorithm>#include<vector>#include<iostream>usingnamespacestd;intmain(){// 生成组合 C(5,3)vector<int>v={1,1,1,0,0};// 3个1,2个0vector<vector<int>>combinations;do{vector<int>comb;for(inti=0;i<v.size();i++){if(v[i]==1)comb.push_back(i+1);// 元素编号1-5}combinations.push_back(comb);}while(prev_permutation(v.begin(),v.end()));// 输出所有组合for(constauto&comb:combinations){for(intnum:comb)cout<<num<<" ";cout<<endl;}return0;}七、算法性能
sort: O(n log n)find: O(n)binary_search: O(log n)(前提已排序)count: O(n)next_permutation: O(n)
总结
在CSP竞赛中,熟练掌握STL算法可以:
- 减少代码量,提高开发效率
- 避免手动实现常见算法错误
- 利用标准库的优化提高性能
- 使代码更易读、易维护
建议在平时练习中多使用这些算法,熟悉它们的参数和返回值,理解它们的时间复杂度,这样才能在竞赛中快速选择并使用合适的算法解决问题。
各种学习资料,助力大家一站式学习和提升!!!
#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"########## 一站式掌握信奥赛知识! ##########";cout<<"############# 冲刺信奥赛拿奖! #############";cout<<"###### 课程购买后永久学习,不受限制! ######";return0;}- 一、CSP信奥赛C++通关学习视频课:
- C++语法基础
- C++语法进阶
- C++算法
- C++数据结构
- CSP信奥赛数学
- CSP信奥赛STL
- 二、CSP信奥赛C++竞赛拿奖视频课:
- 信奥赛csp-j初赛高频考点解析
- CSP信奥赛C++复赛集训课(12大高频考点专题集训)
- 三、考级、竞赛刷题题单及题解:
- GESP C++考级真题题解
- CSP信奥赛C++初赛及复赛高频考点真题解析
- CSP信奥赛C++一等奖通关刷题题单及题解
详细内容:
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转
2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转
3、csp信奥赛冲刺一等奖有效刷题题解:
CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
- 2025 csp-j 复赛真题及答案解析(最新更新)
- 2025 csp-x(山东) 复赛真题及答案解析(最新更新)
- 2025 csp-x(河南) 复赛真题及答案解析(最新更新)
- 2025 csp-x(辽宁) 复赛真题及答案解析(最新更新)
- 2025 csp-x(江西) 复赛真题及答案解析(最新更新)
- 2025 csp-x(广西) 复赛真题及答案解析(最新更新)
- 2020 ~ 2024 csp 复赛真题题单及题解
- 2019 ~ 2022 csp-j 初赛高频考点真题分类解析
- 2021 ~ 2024 csp-s 初赛高频考点解析
- 2023 ~ 2024 csp-x (山东)初赛真题及答案解析
- 2024 csp-j 初赛真题及答案解析
- 2025 csp-j 初赛真题及答案解析(最新更新)
- 2025 csp-s 初赛真题及答案解析(最新更新)
- 2025 csp-x (山东)初赛真题及答案解析(最新更新)
- 2025 csp-x (江西)初赛真题及答案解析(最新更新)
- 2025 csp-x (辽宁)初赛真题及答案解析(最新更新)
CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
- 129 道刷题练习和详细题解,涉及:模拟算法、数学思维、二分算法、 前缀和、差分、深搜、广搜、DP专题、 树和图
4、GESP C++考级真题题解:
GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转
GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转
· 文末祝福 ·
#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"跟着王老师一起学习信奥赛C++";cout<<" 成就更好的自己! ";cout<<" csp信奥赛一等奖属于你! ";return0;}