当前位置: 首页 > news >正文

算法阶段总结1

阶段总结

通过今天晚上的这场div2我深刻的意识到,光是会找窍门是远远不够的,你得会基础的建图,dp,高级数据结构,你这样才可以不断的提升自己,不可以一直在一个阶段停留下去,构造题可以刷下去,但是要开始复习之前的东西和新算法的学习了。为此这篇总结,我将以我现在的代码风格写出算法基础课的所有算法模板。

1.快速排序

// Problem: 快速排序
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/787/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<void(vector<int> &a, int l, int r)> quick_sort = [&](vector<int> &a, int l, int r) -> void {if (l >= r) {return ;}int i = l - 1, j = r + 1, x = a[l + r >> 1];while (i < j) {do {i ++;} while (a[i] < x);do {j --;} while (a[j] > x);if (i < j) {swap(a[i], a[j]);}}quick_sort(a, l, j);quick_sort(a, j + 1, r);};quick_sort(a, 0, n - 1);for (int i = 0; i < n; i ++) {cout << a[i] << " \n"[i == n - 1];}
}int main() {int t;t = 1;while (t --) {solve();}return 0;
}
第k个数
// Problem: 第k个数
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/788/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n, k;cin >> n >> k;vector<int> a(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<int(int l, int r, int k)> quick_sort = [&](int l, int r, int k) -> int {if (l >= r) {return a[l];}int i = l - 1, j = r + 1, x = a[l + r >> 1];while (i < j) {do {i ++;} while (a[i] < x);do {j --;} while (a[j] > x);if (i < j) {swap(a[i], a[j]);}}if (j - l + 1 >= k) {return quick_sort(l, j, k);} else {return quick_sort(j + 1, r, k - (j - l + 1));}};cout << quick_sort(0, n - 1, k) << endl;
}int main() {int t;t = 1;while (t --) {solve();}return 0;
}

2.归并排序

// Problem: 归并排序
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/789/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n), t(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<void(int l, int r)> merge_sort = [&](int l, int r) -> void {if (l >= r) {return ;}int mid = l + r >> 1;merge_sort(l, mid);merge_sort(mid + 1, r);int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) {t[k ++] = a[i ++];} else {t[k ++] = a[j ++];}}while (i <= mid) {t[k ++] = a[i ++];}while (j <= r) {t[k ++] = a[j ++];}for (i = l, k = 0; i <= r; i ++, k ++) {a[i] = t[k];}};merge_sort(0, n - 1);for (int i = 0; i < n; i ++) {cout << a[i] << " \n"[i == n - 1];}
}int main() {int t;t = 1;while (t --) {solve();}return 0;
}
逆序对个数
// Problem: 逆序对的数量
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/790/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n), t(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<i64(int l, int r)> merge_sort = [&](int l, int r) -> i64 {i64 res = 0;if (l >= r) {return 0;}int mid = l + r >> 1;res += merge_sort(l, mid) + merge_sort(mid + 1, r);int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) {t[k ++] = a[i ++];} else {t[k ++] = a[j ++];res += mid - i + 1;}}while (i <= mid) {t[k ++] = a[i ++];}while (j <= r) {t[k ++] = a[j ++];}for (i = l, k = 0; i <= r; i ++, k ++) {a[i] = t[k];}return res;};i64 res = merge_sort(0, n - 1);cout << res << endl;
}int main() {int t;t = 1;while (t --) {solve();}return 0;
}

3.二分

二分不是特别简单的题面都是需要写一个check函数的,check函数是二分的一个难点,因题而异,所以我下面的模板是基于check函数写好以后写的

区间左端点

int l = 0, r = 1e9;
while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;
}

区间右端点

int l = 0, r = 1e9;
while (l < r) {int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;
}

4.高精度

高精度顾名思义就是一些数字太大了,比如有1000位,无法直接进行运算,但是我们可以通过把这些数字放到数组里,然后一位一位的做运算,相当于在模拟咱们手动列竖式的感觉

1.加法

vector<int> add(vector<int> &a, vector<int> &b) {vector<int> res;int t = 0;for (int i = 0; i < a.size() || i < b.size(); i ++) {if (i < a.size()) {t += a[i];}if (i < b.size()) {t += b[i];}res.emplace_back(t % 10);t /= 10;}if (t) {res.emplace_back(t);}return res;
}

2.减法

减法的话,他需要多写一个比较函数,因为咱们只能实现大数减小数,如果是小数减大数的话,通过cmp函数改成大数减小数,并且手动加负号就可以,我在这里只是实现一下这两个函数,

在做完运算后,可能会出现123456 - 123000 = 000456的问题,所以最后我们要去除前导零。

bool cmp(vector<int> &a, vector<int> &b) {if (a.size() != b.size()) {return a.size() > b.size();}for (int i = a.size() - 1; i >= 0; i --) {if (a[i] != b[i]) {return a[i] > b[i];}}return true;
}vector<int> sub(vector<int> &a, vector<int> &b) {vector<int> res;int t = 0;for (int i = 0; i < a.size(); i ++) {t = a[i] - t;if (i < b.size()) {t -= b[i];}res.emplace_back((t + 10) % 10);t = t < 0 ? 1 : 0;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}

3.乘法

乘法的模板我分为两个,一个高精度乘低精度,一个高精度乘高精度,前一个更常用,要比后一个要熟练掌握

vector<int> mul(vector<int> &a, int b) {vector<int> res;int t = 0;for (int i = 0; i < a.size() || t; i ++) {if (i < a.size()) {t += a[i] * b;}res.emplace_back(t % 10);t /= 10;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}
vector<int> mul(vector<int> &a, vector<int> &b) {vector<int> res(a.size() + b.size() + 10);for (int i = 0; i < a.size(); i ++) {for (int j = 0; j < b.size(); j ++) {res[i + j] += a[i] * b[j];}}int t = 0;//完成进位的操作for (int i = 0; i < res.size(); i ++) {t += res[i];res[i] = t % 10;t /= 10;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}

4.除法

由于本人不熟悉除法(我根本没有用过),所以这里我也是复制粘贴来的。原理也不难,可以求得商和余数,一样类比列竖式。

vector<int> div(vector<int> &A, int b, int &r) {vector<int> res;r = 0;for (int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];res.emplace_back(r / b);r %= b;}reverse(res.begin(), res.end());while (res.size() > 1 && res.back() == 0){res.pop_back();}return res;
}

5.前缀和

5.1一维前缀和

这就是给咱们一个数组,然后对他进行一个操作,使得下标为i就是前i项和,这是O(1)的复杂度

vector<int> s(n + 1);
//....
//经过赋值后
for (int i = 1; i <= n; i ++) {s[i] += s[i - 1];
}
//不想改变原数组的话,也可以这样
//vector<int> b(n + 1);
//for (int i = 0; i < n; i ++) {
//    b[i] = b[i - 1] + s[i];
//}

5.2二维前缀和

和上面同理s[i][j]就表示长为j,高为i的矩阵的和

vector<vector<int>> s(n + 10, vector<int> (m + 10));
//...
//经过赋值后
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];}
}

6.差分

这可以看成是前缀和的逆运算

它可以做到对一个区间内用一次操作来加减一个数

也有题的类型是找最小操作数,也是要用差分

6.1一维差分

vector<int> s(n + 1);
for (int i = n; i >= 1; i --) {s[i] -= s[i - 1];
}

6.2二维差分


vector<vector<int>> s(n + 10, vector<int> (m + 10));
//...
//初始化完成后
function<void(int x1, int y1, int x2, int y2, int r)> insert = [&](int x1, int y1, int x2, int y2, int r) -> void {s[x1][y1] += r;s[x2 + 1][y1] -= r;s[x1][y2 + 1] -= r;s[x2 + 1][y2 + 1] += r;
}
for (int i = 1; i <= n; i ++) {for (int j = 1; j <= n; j ++) {insert(i, j, i, j, s[i][j]);}
}while (q --) {int x1, x2, y1, y2, r;cin >> x1 >> y1 >> x2 >> y2, r;insert(x1, y1, x2, y2, r);
}
//来个前缀和复原
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];}
}

7.双指针

​ 常用做法

​ 1.两个指针从头一起走

​ 2.一个指针从头开始,一个指针从尾开始

8.位运算

8.1左移<<

在二进制表示下把数字同时向左移动,高位越界舍弃,低位补零。

8.2 右移>>

在二进制补码表示下把数字同时向右移动,高位以0补充,低位越界舍弃

8.3 与&

二进制表示下两位同时为1则为1,否则为0

8.4 或|

二进制表示下只要有一位为1则为1,否则为0

8.5 异或^

二进制表示下两个不同就为1,相同就为0

9. 离散化

这种题就是一些数字分布在一个很大的区间里,但是数字的总个数很少,开不了这么大的数组,怎么办呢,我们可以利用set和map来离散化,用set来把所有要用到的下标记录下来,然后用map把这些下标映射成1,2,3,4,5…n,然后把值加上去,这就是离散化。

这种感觉得多做题才会有感觉

10.区间合并

这个其实就相当于是一个操作了,能记住就行,记不住也能现推

先把所有的区间都存到一个vector里,然后,传入其中,里面的ed和seg.first的判断会因题做点小改变。

st和ed的初始值记住是极小值就行,因题有可能也会变

void merge(vector<pii> &segs) {vector<pii> res;int st = -2e9, ed = -2e9;sort(segs.begin(), segs.end());for (auto seg : segs) {if (ed < seg.first) {if (st != -2e9) {res.emplace_back(st, ed);}st = seg.first, ed = seg.second;} else {ed = max(ed, seg.second);}}if (st != -2e9) {res.emplace_back(st, ed);}segs = res;
}

相关文章:

算法阶段总结1

阶段总结 通过今天晚上的这场div2我深刻的意识到&#xff0c;光是会找窍门是远远不够的&#xff0c;你得会基础的建图&#xff0c;dp&#xff0c;高级数据结构&#xff0c;你这样才可以不断的提升自己&#xff0c;不可以一直在一个阶段停留下去&#xff0c;构造题可以刷下去&a…...

前端宝典之七:React性能优化实战精华篇

本文主要讲解实战项目中React性能优化的方法&#xff0c;主要分为三个大的方面&#xff1a;减少不必要的组件更新、组件优化以及tree-shaking&#xff0c;共11个方法 一、减少不必要组件更新 以下是一些可以避免在 React 提交阶段进行不必要重新渲染的方法&#xff1a; 1、使…...

【Dash】feffery_antd_components 简单入门示例

一、简单了解 feffery_antd_components 简称 fac &#xff0c;是一个基于 Ant Design 的 Dash 第三方组件&#xff0c;由Feffery 老师开源维护的 Python 网页开发组件库&#xff0c;它具有丰富的页面常用交互组件功能&#xff0c;使开发者可以使用纯Python的方式快速构建现代…...

JAVA学习-练习试用Java实现“路径交叉”

问题&#xff1a; 给定一个整数数组 distance 。从 X-Y 平面上的点 (0,0) 开始&#xff0c;先向北移动 distance[0] 米&#xff0c;然后向西移动 distance[1] 米&#xff0c;向南移动 distance[2] 米&#xff0c;向东移动 distance[3] 米&#xff0c;持续移动。也就是说&#…...

element组件封装

1.上传组件 <!--文件上传组件--> <template><div class"upload-file"><el-uploadref"fileUpload"v-if"props.type default":action"baseURL other.adaptationUrl(props.uploadFileUrl)":before-upload"h…...

Mysql (面试篇)

目录 唯一索引比普通索引快吗 MySQL由哪些部分组成&#xff0c;分别用来做什么 MySQL查询缓存有什么弊端&#xff0c;应该什么情况下使用&#xff0c;8.0版本对查询缓存由上面变更 MyISAM和InnoDB的区别有哪些 MySQL怎么恢复半个月前的数据 MySQL事务的隔离级别&#xff…...

【python】深入探讨python中的抽象类,创建、实现方法以及应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

微前端传值

在微前端架构中&#xff0c;不同子应用之间通过 postMessage 进行通信是一种常见的做法。这种方式允许不同源的窗口之间进行安全的信息交换。 下面是如何使用 postMessage 在微前端环境中发送和接收消息的示例。 步骤 1: 发送消息 假设您有一个主应用&#xff08;host app&a…...

《学会 SpringBoot · 依赖管理机制》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

全网行为管理软件有哪些?5款总有一款适合你的企业!

如今企业越来越依赖互联网进行日常运营和业务发展&#xff0c;网络行为管理变得日益重要。 为了确保网络安全、提高员工工作效率、避免敏感信息外泄等问题&#xff0c;企业往往需要借助全网行为管理软件来监控和管理内部网络的使用情况。 本文将为您介绍五款热门的全网行为管理…...

以简单的例子从头开始建spring boot web多模块项目(二)-mybatis简单集成

继续使用以简单的例子从头开始建spring boot web多模块项目&#xff08;一&#xff09;中的项目进行mybatis集成。 1、pom.xml文件中&#xff0c;增加相关的依赖包的引入&#xff0c;分别是mybatis-spring-boot-starter、lombok、mysql-connector-java 如下&#xff1a; <d…...

Golang | Leetcode Golang题解之第354题俄罗斯套娃信封问题

题目&#xff1a; 题解&#xff1a; func maxEnvelopes(envelopes [][]int) int {n : len(envelopes)if n 0 {return 0}sort.Slice(envelopes, func(i, j int) bool {a, b : envelopes[i], envelopes[j]return a[0] < b[0] || a[0] b[0] && a[1] > b[1]})f : …...

jmeter中添加ip欺骗

1、首先在本机电脑中通过配置文件创建添加ip的配置文件&#xff0c;先创建一个txt格式的&#xff0c;直接修改文件名以及后缀为ips.bat 2、编辑该ips.bat文件&#xff0c;在文件中输入如下内容&#xff0c;用于快速给本机添加ip地址&#xff0c;&#xff08;2&#xff0c;1&…...

WPF篇(19)-TabControl控件+TreeView树控件

TabControl控件 TabControl表示包含多个共享相同的空间在屏幕上的项的控件。它也是继承于Selector基类&#xff0c;所以TabControl也只支持单选操作。另外&#xff0c;TabControl的元素只能是TabItem&#xff0c;这个TabItem继承于HeaderedContentControl类&#xff0c;所以Ta…...

appium下载及安装

下载地址&#xff1a;https://github.com/appium/appium-desktop/releases 双击安装就可以...

XSS项目实战

目录 一、项目来源 二、实战操作 EASY 1 2 3 4 5 6 7 8 一、项目来源 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 二、实战操作 EASY 1 1.Easy -1 2.题目要求及源码 Difficulty is Easy.Pop an alert(1337) on sandbox.pwnfunction.com.No …...

SD-WAN降低网络运维难度的关键技术解析

为什么说SD-WAN&#xff08;软件定义广域网&#xff09;大大降低了网络运维的复杂性&#xff0c;主要是因为它的智能路径选择、应用识别和链路质量监测这三个核心技术。这几项在SD-WAN中尤为重要的技术&#xff0c;它们共同作用&#xff0c;提升了整体网络性能&#xff0c;为网…...

【算法基础实验】图论-最小生成树-Prim的即时实现

理论知识 Prim算法是一种用于计算加权无向图的最小生成树&#xff08;MST, Minimum Spanning Tree&#xff09;的贪心算法。最小生成树是一个连通的无向图的子图&#xff0c;它包含所有的顶点且总权重最小。Prim算法从一个起始顶点开始&#xff0c;不断将权重最小的边加入生成…...

LLama 3 跨各种 GPU 类型的基准测试

2024 年 4 月 18 日&#xff0c;AI 社区对 Llama 3 70B 的发布表示欢迎&#xff0c;这是一款最先进的大型语言模型 &#xff08;LLM&#xff09;。该型号是 Llama 系列的下一代产品&#xff0c;支持广泛的用例。该模型 istelf 在广泛的行业平台上表现良好&#xff0c;并提供了新…...

FreeRTOS 快速入门(五)之信号量

目录 一、信号量的特性1、信号量跟队列的对比2、两种信号量的对比 二、信号量1、二值信号量1.1 二值信号量用于同步1.2 二值信号量用于互斥 2、计数信号量 三、信号量函数1、创建2、删除3、give/take 一、信号量的特性 信号量&#xff08;Semaphore&#xff09;是一种实现任务…...

centos 服务器之间实现免密登录

为了在CentOS服务器之间实现免密登录&#xff0c;你需要使用SSH的公钥认证机制 比如两台centos系统的服务器A 和服务器B 首先我们实现从A服务器可以免密登录到服务器B上 首先生成公钥和秘钥&#xff1a; ssh-keygen -t rsa 生成了公钥和秘钥之后&#xff1a; ssh-copy-id r…...

RabbitMq实现延迟队列功能

1、rabbitmq服务端打开延迟插件 &#xff08;超过 4294967295毫秒 ≈ 1193 小时 ≈ 49.7 天 这个时间会立即触发&#xff09; 注意&#xff1a;只有RabbitMQ 3.6.x以上才支持 在下载好之后&#xff0c;解压得到.ez结尾的插件包&#xff0c;将其复制到RabbitMQ安装目录下的plug…...

redis内存淘汰策略

1. redis内存淘汰策略 日常常用&#xff1a;allkeys-lru&#xff1a;在键空间中移除最近最少使用的key。1.1 为什么需要使用redis内存淘汰策略? 因为我们服务器中的内存是有限的,不会无限多,所以需要对一些不常用的key进行内存清理.1.2 redis内存淘汰策略有哪些? redis默认…...

实时洞察应用健康:使用Spring Boot集成Prometheus和Grafana

1. 添加Prometheus和Actuator依赖 在pom.xml中添加Spring Boot Actuator和Micrometer Prometheus依赖&#xff1a; <dependencies> <!--监控功能Actuator--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring…...

生信圆桌x生信豆芽菜:生物信息学新手的学习与成长平台

生信豆芽菜是一个专门为生物信息学初学者创建的学习与交流平台&#xff0c;致力于帮助新手们快速入门并掌握生信分析的基础知识与技能。随着生物信息学在科研中的重要性日益提升&#xff0c;越来越多的学生和研究人员开始接触这一领域。生信豆芽菜正是为了满足这些新手的需求&a…...

创客匠人标杆对话(上):她如何通过“特长+赛道”实现财富升级

老蒋创客圈第64期对话标杆直播连麦&#xff0c;本期我们邀请到【iAMU蒙特梭利翻转星球】平台创始人申晓慧老师。 为我们揭秘“如何挖掘人生首个百万&#xff0c;实现财富升级&#xff1f;”&#xff0c;深度分享如何提炼用户痛点&#xff0c;高效引流新用户&#xff1f;如何通…...

最少钱学习并构建大模型ollama-llama3 8B

学习大模型时可能面临一些困难&#xff0c;这些困难可能包括&#xff1a; 计算资源限制&#xff1a;训练大模型通常需要大量的计算资源&#xff0c;包括CPU、GPU等。如果设备资源有限&#xff0c;可能会导致训练时间长、效率低下或无法完成训练。 内存限制&#xff1a;大模型通…...

AVI视频损坏了怎么修复?轻松几步解决你的困扰

在数字化时代&#xff0c;视频已成为我们记录生活、分享经验和传递信息的重要方式。AVI作为一种常见的视频格式&#xff0c;因其无损质量的特点而受到广泛欢迎。然而&#xff0c;有时候我们可能会遇到AVI视频文件损坏的情况&#xff0c;导致无法正常播放。别担心&#xff0c;本…...

【C++】map、set基本用法

欢迎来到我的Blog&#xff0c;点击关注哦&#x1f495; 前言: C的STL已经学习很大一部分了&#xff0c;接下来介绍的是map set是c的是两种关联容器。 简单介绍 map set&#xff1a; 两者都使用红黑树作为底层数据结构来存储元素。map是一种键值对容器&#xff0c;其中每个键…...

模型 闭环原理

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。反馈驱动&#xff0c;持续循环&#xff0c;缺陷亦被放大。 1 闭环原理的应用 1.1 闭环原理解读 AI自我训练&#xff0c;从人工智能变成人工智障 这里主要使用闭环原理来解释 AI 自我训练导致的问题。…...