目录:
1.STL的应用。
2.搜索方面的一些知识。
3.图论最短路径生成。
一,STL
基础内容:
STL数据库复习_钟一淼的博客-CSDN博客
STL函数补充_钟一淼的博客-CSDN博客
淼淼的STL总结_钟一淼的博客-CSDN博客
进阶知识:
1.vector
应用场景:
a.适用于随机访问,访问量比较大(因为随机访问的时间复杂度只有O(1)),相对而言插入和删除操作较小。
b.结合本周所学习的图论,可以用vector建立邻接表,代码如下:
struct node {
int s1;//记录结点
int side;//边权
}
vector<node>mp[maxn];//本身就可以存储结构体
//也可以用vector<pair<int,int>>s
init();//初始化mp
node h;
//循环输入
int x,y,r;
h.s1 = y;
h.side = r;
mp[x].push_back(h);//从x到y,路径为r
注意的是vector可以设为二维数组进行操作。 (pair的用法之前有讲)。
c.经典->约瑟夫问题:
P1996 约瑟夫问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1996 题目分析:
1.本题形成了一个圆桌问题。(寻找到的点对数组现有元素个数进行取余)
2.找到的点删除,直到数组为空。
#include <iostream>
#include <vector>
using namespace std;
vector<int>s;
//感觉知识掌握的还是不够牢固
int main()
{
int n, m;
int pos = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
s.push_back(i);
}
while (!s.empty()) {
pos = (pos + m-1) % s.size();
cout << s[pos] << " ";
s.erase(s.begin()+pos);
}
}
2.stack
应用场景:
1.需要逆序输出时(因为栈的最大特点就是先进后出)
2.计算后缀表达式(例如:括号匹配,符号成对出现等)
3.数制转换也可以用栈来实现。
栈的例题:
例题1:
P1449 后缀表达式 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1449
题目分析:
代码如下:
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
int s=0;
char ch;
stack<int>n;
int main()
{
int x;
int y;
do {
ch = getchar();
if (ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
}
else if (ch == '.') {
n.push(s);
s = 0;
}
else if (ch != '@') {
x = n.top(); n.pop();
y= n.top(); n.pop();
switch (ch)
{
case '+':n.push(x + y); break;
case '-':n.push(y-x); break;//是栈顶的第二个元素-第一个元素
case '*':n.push(x *y); break;
case '/':n.push(y/x); break;
}
}
} while (ch != '@');
cout << n.top()<<endl;//取剩余的栈顶元素
}
例题2:
十进制转二进制,(因为栈这个本质是一个先进后出的结构)。
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
vector<int>s;
//感觉知识掌握的还是不够牢固
int main()
{
stack<int>s;
int n;
cin >> n;
while (n>0) {
s.push(n % 2);
n = n / 2;
}
int size = s.size();
for (int i =0; i <size; i++) {
cout << s.top();
s.pop();
}
}
3.queue
应用场景:
详情队列使用请看:
SPFA算法(最短路径算法)_钟一淼的博客-CSDN博客
BFS迷宫问题_钟一淼的博客-CSDN博客
总体来说,这是我最熟悉的STL里的函数,队列的使用范围是比较广泛的,但是仍然要注意队列的一些基础操作。特别是关于搜索问题的回溯方面,一定要特别注意。
4.priority_queue 优先队列
概念解析:
无非就是优先级高的先进行出队操作。就是个大顶堆的操作,最大的元素在堆顶(回想堆排序我到现在还没写,今晚赶出来)
例题:
(这里例题来源于费费的课件,因为我觉得这个题目就很适合我理解优先队列的使用,我很菜)
判断下列的点哪个离原点最远,并输出那个点的x,y值。
输入:(输入n,接下来输入n个点)
3
3 2
1 2
2 2
输出:(输出最大距离那个点的x,y坐标)
3 2
利用优先队列,运算符重载,代码如下:
#include<iostream>
#include <queue>
#define pow2(a)((a)*(a))//宏定义
#define dist2(x,y)(pow2(x)+pow2(y))
using namespace std;
struct node {
int x;
int y;
friend bool operator<(node a,node b) {//运算符重载,重载这个"<"
return (dist2(a.x, a.y) < dist2(b.x, b.y));
/*const bool operator<(const node&b){//运算符重载,重载这个"<"
return (dist2(x,y)<dist2(b.x,b.y));
}(这个报错了)*/
}
};
int main()
{
priority_queue<node>s;
int n;
int x, y;
cin >> n;
while (n--) {
node p;// p定义一个结构体类型的变量,接收x,y;
cin >> x >> y;
p.x = x; p.y = y;
s.push(p);
}
cout << s.top().x << " " << s.top().y << endl;
}
6.sort
sort,可谓是我接触的最多的函数了。
应用场景:
1.给无序数组进行排序。(可以是任何类型,进行降序,升序)
2.用于结构体排序(应用十分广泛,主要是将bool cmp函数给写好,自定义排序准则)
例题:(关于结构体排序的一道题目)
P1068 [NOIP2009 普及组] 分数线划定 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1068题目分析:(
说实话,我都不想分析,对我来说这个不太难懂)
代码如下:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct student {
int nums;
int score;
}a[6000];
bool cmp(student x, student y) {//判断准则
if (x.score == y.score) {
return x.nums < y.nums;
}
return x.score > y.score;
}
int main()
{
int n, m;
int p = 0;
int k = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i].nums >> a[i].score;
}
sort(a + 1, a + n + 1, cmp);
p =floor(m*1.5);
for (int i = p; i <= n; i++) {
if (a[p].score == a[i].score) {
k = i;//记录下标
}
}
cout << a[p].score << " " << k << endl;
for (int i = 1; i <= k-1; i++) {
cout << a[i].nums << " " << a[i].score << endl;
}
cout << a[k].nums << " " << a[k].score;
}
7.unique(去重函数)
应用场景:
就是去除相邻元素的重复值,只保留一个相同的元素。
所以,注意的是使用之前先用sort进行排序。(其实重复的值并没有被删除,而是排到了数组后面去了)。
代码实现一下(特别水):
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
int a[100];
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
int h = unique(a, a + n) - a;//用一个新的数接收去重之后数组的长度
for (int i = 0; i < h; i++) {
cout << a[i] << " ";
}
}
8.next_permutation(全排列)
分析:
按字典序进行全排列。
我们学校的例题:
OpenJudge - 7:全排列2http://sdau.openjudge.cn/huisu/7/水一道代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
int n;
cin >> n;
int a[15];
for (int i = 1; i <= n; i++) {
a[i] = i;
}
do {
for (int i = 1; i <= n; i++) {
cout << a[i] << " ";
}
cout << endl;
} while (next_permutation(a + 1, a + n + 1));
}
9.upper_bound、lower_bound
解析:
10.set/multiset(集合)
基础知识里面基本操作总结的已经很全面了,因为本人只做过一道关于set集合的题目,具体应用场景还待我继续研究(其实我是真的不知道这个用在哪)
11.map/multimap
分析:
映射的原理,用键值返回元素。
应用例题:
P5266 【深基17.例6】学籍管理 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5266
题目分析:
#include <iostream>
#include <map>
using namespace std;
map<string, int>s;
int n,m;
string name;
int score;
int main()
{
cin >> n;
while (n--) {
cin >> m;
if (m == 1) {
cin >> name >> score;
s[name] = score;
cout << "OK" << endl;
}
else if (m == 2) {
cin >> name;
if (s.find(name) != s.end()) {
cout << s[name] << endl;
}
else {
cout << "Not found" << endl;
}
}
else if (m == 3) {
cin >> name;
if (s.find(name) != s.end()) {
s.erase(s.find(name));
cout << "Deleted successfully" << endl;
}
else {
cout << "Not found" << endl;
}
}
else {
cout << s.size() << endl;
}
}
}
二,图的最短路径算法
直接看我关于图的总结吧->
图论:图的四种最短路径算法_钟一淼的博客-CSDN博客
三,最终总结:
1.个人觉得还是在细节上的把握很差。(特别是STL在算法中应用很广泛)
2.周六周日的任务就是将这周所学习的知识复习,不能只贪图速度而忽视效率。
3.算法这个东西就是要多思考,不能盲目的刷题,这周的东西还是不少,灵活运用才是关键。
4.也是刚开始写这个博客,所以有什么不好的地方还是需要及时指正。
5.希望能通过本周的学习,复习,总结,形成更强的知识网络体系,最终实践在题目中去。
那这周的总结就到这里结束了,细节的补充还会继续更新,生死看淡,不服就干!