算法阶段总结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我深刻的意识到,光是会找窍门是远远不够的,你得会基础的建图,dp,高级数据结构,你这样才可以不断的提升自己,不可以一直在一个阶段停留下去,构造题可以刷下去&a…...
前端宝典之七:React性能优化实战精华篇
本文主要讲解实战项目中React性能优化的方法,主要分为三个大的方面:减少不必要的组件更新、组件优化以及tree-shaking,共11个方法 一、减少不必要组件更新 以下是一些可以避免在 React 提交阶段进行不必要重新渲染的方法: 1、使…...
【Dash】feffery_antd_components 简单入门示例
一、简单了解 feffery_antd_components 简称 fac ,是一个基于 Ant Design 的 Dash 第三方组件,由Feffery 老师开源维护的 Python 网页开发组件库,它具有丰富的页面常用交互组件功能,使开发者可以使用纯Python的方式快速构建现代…...
JAVA学习-练习试用Java实现“路径交叉”
问题: 给定一个整数数组 distance 。从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说&#…...
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由哪些部分组成,分别用来做什么 MySQL查询缓存有什么弊端,应该什么情况下使用,8.0版本对查询缓存由上面变更 MyISAM和InnoDB的区别有哪些 MySQL怎么恢复半个月前的数据 MySQL事务的隔离级别ÿ…...
【python】深入探讨python中的抽象类,创建、实现方法以及应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
微前端传值
在微前端架构中,不同子应用之间通过 postMessage 进行通信是一种常见的做法。这种方式允许不同源的窗口之间进行安全的信息交换。 下面是如何使用 postMessage 在微前端环境中发送和接收消息的示例。 步骤 1: 发送消息 假设您有一个主应用(host app&a…...
《学会 SpringBoot · 依赖管理机制》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
全网行为管理软件有哪些?5款总有一款适合你的企业!
如今企业越来越依赖互联网进行日常运营和业务发展,网络行为管理变得日益重要。 为了确保网络安全、提高员工工作效率、避免敏感信息外泄等问题,企业往往需要借助全网行为管理软件来监控和管理内部网络的使用情况。 本文将为您介绍五款热门的全网行为管理…...
以简单的例子从头开始建spring boot web多模块项目(二)-mybatis简单集成
继续使用以简单的例子从头开始建spring boot web多模块项目(一)中的项目进行mybatis集成。 1、pom.xml文件中,增加相关的依赖包的引入,分别是mybatis-spring-boot-starter、lombok、mysql-connector-java 如下: <d…...
Golang | Leetcode Golang题解之第354题俄罗斯套娃信封问题
题目: 题解: 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的配置文件,先创建一个txt格式的,直接修改文件名以及后缀为ips.bat 2、编辑该ips.bat文件,在文件中输入如下内容,用于快速给本机添加ip地址,(2,1&…...
WPF篇(19)-TabControl控件+TreeView树控件
TabControl控件 TabControl表示包含多个共享相同的空间在屏幕上的项的控件。它也是继承于Selector基类,所以TabControl也只支持单选操作。另外,TabControl的元素只能是TabItem,这个TabItem继承于HeaderedContentControl类,所以Ta…...
appium下载及安装
下载地址: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(软件定义广域网)大大降低了网络运维的复杂性,主要是因为它的智能路径选择、应用识别和链路质量监测这三个核心技术。这几项在SD-WAN中尤为重要的技术,它们共同作用,提升了整体网络性能,为网…...
【算法基础实验】图论-最小生成树-Prim的即时实现
理论知识 Prim算法是一种用于计算加权无向图的最小生成树(MST, Minimum Spanning Tree)的贪心算法。最小生成树是一个连通的无向图的子图,它包含所有的顶点且总权重最小。Prim算法从一个起始顶点开始,不断将权重最小的边加入生成…...
LLama 3 跨各种 GPU 类型的基准测试
2024 年 4 月 18 日,AI 社区对 Llama 3 70B 的发布表示欢迎,这是一款最先进的大型语言模型 (LLM)。该型号是 Llama 系列的下一代产品,支持广泛的用例。该模型 istelf 在广泛的行业平台上表现良好,并提供了新…...
FreeRTOS 快速入门(五)之信号量
目录 一、信号量的特性1、信号量跟队列的对比2、两种信号量的对比 二、信号量1、二值信号量1.1 二值信号量用于同步1.2 二值信号量用于互斥 2、计数信号量 三、信号量函数1、创建2、删除3、give/take 一、信号量的特性 信号量(Semaphore)是一种实现任务…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
