0
点赞
收藏
分享

微信扫一扫

ACM第一周总结(STL)

古月无语 2022-03-19 阅读 141

目录:

一,STL

基础内容:

进阶知识:

1.vector

应用场景:

2.stack

应用场景:

栈的例题:

3.queue

应用场景:

4.priority_queue 优先队列

概念解析:

例题:

6.sort

应用场景:

例题:(关于结构体排序的一道题目)

7.unique(去重函数)

应用场景:

8.next_permutation(全排列)

分析:

9.upper_bound、lower_bound

解析:

10.set/multiset(集合)

11.map/multimap

分析:

应用例题:

题目分析:

二,图的最短路径算法

三,最终总结:


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.希望能通过本周的学习,复习,总结,形成更强的知识网络体系,最终实践在题目中去。

        那这周的总结就到这里结束了,细节的补充还会继续更新,生死看淡,不服就干!

举报

相关推荐

寒假第一周总结

第一周

Vue第一周复习总结

第一周学习情况总结

大一寒假第一周总结

打卡第一周

第一周学习

第一周编程

0 条评论