AcWing算法基础课——简单算法模板

 说明

        本篇文章只给出代码模板,以及自己对该模板的理解。如果想看正确的算法思路,可以移步AcWing官网看详情。链接:常用代码模板1——基础算法 - AcWing
        如有理解错误,欢迎大家批评指正。

简单算法模板

一、排序

1.1 快速排序模板

void quick_sort(int q[],int l,int r){//q是传入的数组,[l,r]是需要排序的范围if(l>=r) return;int i = l-1,j = r+1,x = q[l+r>>1];while(i<j){do i++;while(q[i]<x);do j--;while(q[j]>x);if(i<j) swap(q[i],q[j]);}quick_sort(q,l,j),quick(q,j+1,r);
}

1.2 归并排序

int tmp[N];//需要开一个临时数组tmp[],N至少跟传入的q[]数组的范围一致
void merge_sort(int q[],int l,int r){if(l>=r) return;int mid = r+l>>1;merge_sort(q,l,mid),merge_sort(q,mid+1,r);int k = 0,i = l,j = mid+1;while(i<=mid&&j<=r){if(q[i]<=q[j]) tmp[k++]=q[i++];else tmp[k++]=q[j++];}while(i<=mid) tmp[k++]=q[i++];while(j<=r) tmp[k++]=q[j++];for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}

二、 二分

2.1 整数二分模板1

bool check(int x){//check函数检查x是否满足某种性质//根据题意完善check()函数
}
//区间被划分为[l,mid],[mid+1,r]
int bsearch1(int l,int r){while(l<r){int mid=l+r>>1;if(check(mid)) r=mid;else l=mid+1;}return l;
}

2.2 整数二分模板2

bool check(int x){//check函数检查x是否满足某种性质//根据题意完善check()函数
}
//区间被划分为[l,mid-1],[mid,r]
int bsearch2(int l,int r){while(l<r){int mid=l+r+1>>1;if(check(mid)) l=mid;else r=mid+1;}return l;
}

浮点数二分模板

bool check(double x){//check函数检查x是否满足某种性质//根据题意完善check()函数
}
double bsearch3(double l,double r){const double eps = 1e-8;//定义精度:如果题目要求精确到小数点后六位小数,eps最好开到1e-8保险while(r-l>eps){double mid = (l+r)/2;if(check(mid)) r = mid;else l = mid;}return l;
}

三、高精度

3.1 高精度大数的存储

string a;cin >> a;//以字符串读入大整数
vector<int> A;//使用vector<int> A从个位往高位存储即逆序存储
for(int i = a.size()-1;i>=0;i--) A.push_back(s[i]-'0');

3.2 A+B模板

//C=A+B,A>=0,B>=0
//C++中&还可用于引用变量,常用于传参和定义别名
//如第6行代码,若写成
//vector<int> add(vector<int A,vector<int> B){
//可能会爆内存并且会严重拖慢程序运行速度
vector<int> add(vector<int> &A,vector<int> &B){//参数为大整数A,B,返回A+B的vectorif(A.size()<B.size()) return add(B,A);vector<int> C;int t = 0;//t表示进位for(int i = 0;i<A.size();i++){t+=A[i];if(i<B.size()) t+=B[i];C.push_back(t%10);t/=10;}if(t) C.push_back(t);//如果最高位还有进位,则放入C中return C;
}

3.3 A-B模板

//C=A-B,A>=0,B>=0
vector<int> sub(vector<int> &A,vector<int> &B){//参数为大整数A,B,返回A-B的vectorvector<int> C;int t = 0;//t表示借位for(int i = 0;i<C.size();i++){t=A[i]-t;if(i<B.size()) t-=B[i];C.push_back((t+10)%10);//(t+10)是为了防止t为负数导致取模后出现负数if(t<0) t=1;//有借位else t=0;//没有借位}while(C.size()>1&&C.back()==0) C.pop_back();//去除前导零return C;
}

3.4 A*b模板

//C=A*b,A>=0,b>=0
vector<int> mul(vector<int> &A,int b){//参数为大整数A,小整数b,返回A*b的vectorvector<int> C;int t = 0;//t表示进位值(区别于A+B的进位,t可能是很大的)for(int i = 0;i<A.size()||t;i++){if(i<A.size()) t+=A[i]*b;C.push_back(t%10);t/=10;}while(C.size()>1&&C.back()==0) C.pop_back();//去除前导零return C;
}

3.5 A/b模板

//A/b==C...r,A>=0,b>=0
vector<int> div(vector<int> &A,int b,int &r){//参数为大整数A,小整数b,r用于带回计算出的余数vector<int> C;r = 0;for(int i = A.size();i>=0;i--){r=r*10+A[i];C.push_back(r/b);r%=b;}reverse(C.begin(),C.end());//反转C,方便去除前导零和输出while(C.size()>1&&C.back()==0) C.pop_back();//去除前导零return C;
}

四、前缀和、差分

4.1 一维前缀和模板

//如果我们要求数组a[]大量的子区间[l,r]的数之和
const int N = 1e6+5;
int a[N],prefix[N];//preifx[]为前缀和数组
void solve(){int n;cin >> n;//有n个数,1<=n<=1000000for(int i = 1;i<=n;i++) cin >> a[i];//下标一定从1开始//计算前缀和for(int i = 1;i<=n;i++) prefix[i]=prefix[i-1]+a[i];int q;cin >> q;//有q次询问while(q--){int l,r;cin >> l >> r;//[l,r]为询问区间//输出子区间[l,r]的数之和cout << prefix[r]-prefix[l-1] << endl;//endl -> '\n'}
}

4.2 二维前缀和模板

//如果我们要求矩阵a[][]大量的子矩阵(a[x1][y1]和a[x2][y2]组成的子矩阵)的数之和
const int N = 1e3+5;
int a[N][N],prefix[N][N];//prefix[][]为前缀和数组
void solve(){int n;cin >> n;//n行n列的矩阵,1<=n<=1000for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) cin >> a[i][j];//下标从1开始//计算前缀和for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){prefix[i][j]=prefix[i-1][j]+prefix[i][j-1]+a[i][j]-preifx[i-1][j-1];}}int q;cin >> q;//q次询问while(q--){int x1,y1,x2,y2;cin >> x1 >> y1 >> x2 >> y2;//子矩阵的范围//输出子矩阵数之和cout << prefix[x2][y2]-preifx[x1-1][y2]-prefix[x2][y1-1]+prefix[x1-1][y1-1] << endl;//endl -> '\n'}
}

4.3 一维差分模板

//如果我们要大量统一修改数组a[]的区间[l,r]的值,使该区间的数都加上x,并要我们输出最终修改后的数组
const int N = 1e6+5;
int a[N],diff[N];//diff[]为差分数组
void solve(){int n;cin >> n;//有n个数,1<=n<=1000000for(int i = 1;i<=n;i++) cin >> a[i];//下标从1开始//计算差分数组for(int i = 1;i<=n;i++) diff[i]=a[i]-a[i-1];int q;cin >> q;//q次修改while(q--){int l,r,x;cin >> l >> r >> x;//[l,r]区间内的数都加xdiff[l]+=x,diff[r+1]-=x;}for(int i = 1;i<=n;i++) a[i]=a[i-1]+diff[i];//构造修改后的数组a[]for(int i = 1;i<=n;i++) cout << a[i] << " \n"[i==n];//遍历输出,输出完最后一个数后输出换行
}

4.4 二维差分模板

//如果我们要大量统一修改矩阵a[][]的子矩阵(a[x1][y1]和a[x2][y2]形成的子矩阵),使该区间都加上x,并要我们输出最终修改后的数组
const int N = 1e3+5;
int a[N][N],diff[N][N];//diff[][]为差分数组
void update(int x1,int y1,int x2,int y2,int x){diff[x1][y1]+=x,diff[x2+1][y2+1]+=x,diff[x1][y2+1]-=x,diff[x2+1][y1]-=x;
}
void solve(){int n;cin >> n;//n行n列的矩阵,1<=n<=1000for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++) cin >> a[i][j];//下标从1开始//计算差分数组for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){update(i,j,i,j,a[i][j]);//计算其实就是每次修改一个1×1的小矩阵}}int q;cin >> q;//q次询问while(q--){int x1,y1,x2,y2;cin >> x1 >> y1 >> x2 >> y2;//子矩阵的范围//实现修改update(x1,y1,x2,y2,x);}//构造回最终修改后的矩阵a[][]for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]-diff[i][j];}}//遍历输出,输出完一行后换行for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++) cout << a[i][j] << " \n"[j==n];}
}

五、双指针

5.1 双指针模板

bool check(int i,int j){//具体问题的逻辑
}
void solve(){for(int i = 0,j=0;i<n;i++){while(j<i&&check(i,j)) j++;//具体问题的逻辑}
}
//常见问题分类:
//    (1) 对于一个序列,用两个指针维护一段区间
//    (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
//上述分类大致都包含快慢指针和对撞指针等例题

六、位运算

情景1

        求整数n的第k位二进制数字

情景1模板

int find(int n){return n>>k&1;
}
void solve(){int n;cin >> n;//读入ncout << find(n) << endl;//调用函数并输出结果
}

情景2

        求整数n的二进制表示中最低位的1的值

情景2模板

int lowbit(int n){//这个计算就被称为lowbit操作return n&(-n);
}
//如:求6的lowbit,6表示二进制补码为(0……0110)即29个'0'+"110"
//-6的补码为(1……1010)即29个'1'+"010"
//而(0……0110)&(1……1010) --> (0……0010)即结果的二进制为30个'0'+"10",转换为十进制的值为2
void solve(){int n;cin >> n;//读入ncout << lowbit(n) << endl;//调用函数并输出结果
}

七、离散化

7.1 离散化模板

vector<int> alls;//存储所有待离散化的值
//使用vector排序去重(要求会默写)
sort(alls.begin(),alls.end());
alls.erase(unique(alls.begin(),alls.end()),alls.end());
// 二分求出x对应的离散化的值
int find(int x){//找到第一个大于等于x的位置int l=0,r=alls.size()-1;while (l<r){int mid=l+r>>1;if(alls[mid]>=x) r=mid;else l=mid+1;}return r+1;//映射到1,2,...,n
}

八、 区间合并

8.1 区间合并模板

// 将所有存在交集的区间合并
void merge(vector<PII> &segs){//PII->pair<int,int>,pair存储的是左端点l和右端点r的二元组,合并后的结果放回segsvector<PII> res;sort(segs.begin(),segs.end());int st=-2e9,ed=-2e9;for(auto seg:segs){if(ed<seg.first){if(st!=-2e9) res.push_back({st,ed});st=seg.first,ed=seg.second;}else ed=max(ed,seg.second);}if (st!=-2e9) res.push_back({st, ed});segs=res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/733638.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1950-2022年各区县逐年平均降水量数据

1950-2022年各区县逐年平均降水量数据 1、时间&#xff1a;1950-2022年 2、指标&#xff1a;省逐年平均降水量 3、范围&#xff1a;33省&#xff08;不含澳门&#xff09;、360地级市、2800个县 4、指标解释&#xff1a;逐年平均降水数据是指当年的日降水量的年平均值&…

力扣面试经典150 —— 11-15题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 11. [中等] H指…

【Web - 框架 - Vue】随笔 - Vue CLI - 快速上手

Vue CLI 创建Vue CLI项目 【步骤】 命名项目空间&#xff1a;在电脑里创建文件夹&#xff0c;用于存储所有项目&#xff1b;定位项目空间&#xff1a;在"CMD窗口"里定位到工程的项目空间上&#xff1b; 方法1&#xff1a;(a)用"WINR"打开运行窗口&#x…

Fastjson 1.2.24 反序列化导致任意命令执行漏洞复现(CVE-2017-18349)

写在前面 CVE-2017-18349 指的是 fastjson 1.2.24 及之前版本存在的反序列化漏洞&#xff0c;fastjson 于 1.2.24 版本后增加了反序列化白名单&#xff1b; 而在 2019 年&#xff0c;fastjson 又被爆出在 fastjson< 1.2.47 的版本中&#xff0c;攻击者可以利用特殊构造的 …

retrofit2中,响应参数的int类型会被转为double小数点的解决办法。

背景 retrofit2版本&#xff1a;2.3.0 我使用retrofit2作为接口请求框架。 但是我发现在响应时&#xff0c;解析的响应内容总会有问题。 例如&#xff1a; {"msg":"","code":0.0,"data":"123"}其中的"code"应该…

简述epoll实现

所有学习笔记&#xff1a;https://github.com/Dusongg/StudyNotes 文章目录 epoll数据结构的选择&#xff1f;以tcp为例&#xff0c;网络io的可读可写如何判断&#xff1f;epoll如何做到线程安全&#xff1f;LT和ET如何实现&#xff1f;tcp状态和io的读写有哪些关系&#xff1…

新概念英语第二册(73)

【New words and expressions】生词和短语&#xff08;9&#xff09; record-holder 纪录保持者 truant n. 逃学的孩子unimaginative adj. 缺乏想像力的shame n. 惭愧&#xff0c;羞耻 hitchhike v. 搭便车旅行 m…

Linux fbset命令教程:如何使用fbset命令修改帧缓冲设备设置(附实例详解和注意事项)

Linux fbset命令介绍 fbset是一个系统实用程序&#xff0c;用于显示或更改帧缓冲设备的设置。帧缓冲设备提供了一个简单且独特的接口&#xff0c;用于访问不同类型的图形显示。帧缓冲设备通过位于/dev目录中的特殊设备节点进行访问。 Linux fbset命令适用的Linux版本 fbset命…

【C语言】linux内核tcp_write_xmit和tcp_write_queue_purge

tcp_write_xmit 一、讲解 这个函数 tcp_write_xmit 是Linux内核TCP协议栈中的一部分&#xff0c;其基本作用是发送数据包到网络。这个函数会根据不同情况推进发送队列的头部&#xff0c;确保只要远程窗口有空间&#xff0c;就可以发送数据。 下面是对该函数的一些主要逻辑的中…

Spring Boot单元测试与热部署简析

1 Spring Boot的简介 Spring Boot是一个用于构建独立的、生产级别的Spring应用程序的框架。它简化了Spring应用程序的开发过程&#xff0c;提供了自动配置和默认配置&#xff0c;使得开发者只需专注于业务逻辑的实现&#xff0c;而不用去关注繁琐的配置问题。 Spring …

ElasticSearch 底层读写原理

ElasticSearch 底层读写原理 ​ 写请求是写入 primary shard&#xff0c;然后同步给所有的 replica shard&#xff1b;读请求可以从 primary shard 或 replica shard 读取&#xff0c;采用的是随机轮询算法。 1、ES写入数据的过程 1.选择任意一个DataNode发送请求&#xff0c…

Java17 --- springCloud之LoadBalancer

目录 一、LoadBalancer实现负载均衡 1.1、创建两个相同的微服务 1.2、在客户端80引入loadBalancer的pom 1.3、80服务controller层&#xff1a; 一、LoadBalancer实现负载均衡 1.1、创建两个相同的微服务 1.2、在客户端80引入loadBalancer的pom <!--loadbalancer-->&…

WPF 窗口添加投影效果Effect

BlurRadius&#xff1a;阴影半径 Color&#xff1a;颜色 Direction&#xff1a;投影方向 ShadowDepth&#xff1a;投影的深度 <Window.Effect><DropShadowEffect BlurRadius"10" Color"#FF858484" Direction"300" ShadowDepth&quo…

LLM长上下文外推方法

现在的LLM都集中在卷上下文长度了&#xff0c;最新的Claude3已经支持200K的上下文&#xff0c;见&#xff1a;cost-context。下面是一些提升LLM长度外推能力的方法总结&#xff1a; 数据工程 符尧大佬的最新工作&#xff1a;Data Engineering for Scaling Language Models to …

【Nestjs实操】环境变量和全局配置

一、环境变量 1、使用dotenv 安装pnpm add dotenv。 根目录下创建.env文件&#xff0c;内容如下&#xff1a; NODE_ENVdevelopment使用 import {config} from "dotenv"; const path require(path); config({path:path.join(__dirname,../.env)}); console.log(…

探索代理服务器:保护您的网络安全与隐私

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 隐藏真实IP地址&#xff1a; 访问控制&#xff1a; 加速访问速度&#xff1a; 过滤内容&#xff1a; 突破访问限制&#xff1…

Python图像处理:1.插值、频域变换与对比度增强

一、几何变换 7.图像的插值 (1)原理介绍 下面对比三种插值方法&#xff0c;分别是最近邻插值法、双线性插值法、卷积插值法&#xff0c;三种方法的前提和特点、优缺点、适用场景如下&#xff1a; 最近邻插值&#xff08;Nearest Neighbor Interpolation&#xff09;&#xf…

Effective C++ 学习笔记 条款20 宁以pass-by-reference替换pass-by-value

缺省情况下C以by value方式&#xff08;一个继承自C的方式&#xff09;传递对象至&#xff08;或来自&#xff09;函数。除非你另外指定&#xff0c;否则函数参数都是以实际实参的副本为初值&#xff0c;而调用端所获得的亦是函数返回值的一个副本。这些副本系由对象的copy构造…

Linux网络套接字补充

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 目录 一、地址转换函数 二、TCP协议通讯流程 三、…

GPT-prompt大全

ChatGPT目前最强大的的工具是ChatGPT Plus&#xff0c;不仅训练数据更新到了2023年&#xff0c;而且还可以优先访问新功能。对于程序员来说&#xff0c;升级到ChatGPT Plus&#xff0c;将会带来更多的便利和效率提升。 根据 升级ChatGPT Plus保姆级教程&#xff0c;1分钟就可以…