基础算法
文章平均质量分 65
在本专栏将会讲解一些写算法题用到的基础的算法知识及代码模版等
少年负剑去
这个作者很懒,什么都没留下…
展开
-
数论-1、质数
如果 n%d=0,则 n%(n/d)=0,所以只需枚举 d ⩽ n/d,所以 d ⩽ 根号n。因为 n 中最多只有一个大于 sqrt(n) 的质因子,所以可以对数据范围进行优化一下,将 n 与 1 这两个质因子单独处理。对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。给定 n 个正整数 ai,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。在大于1的整数中,如果只包含1和本身这两个约数,就被称之为质数,或者叫做素数。原创 2024-11-04 17:45:54 · 471 阅读 · 0 评论 -
7、哈希表
p进制假设A-Z个字母 求出这个数组的十进制数字(相加的结果可能过于大 所以mod上一个数字) 、就可以把整个数字映射到0 - Q-1上。原创 2024-10-25 22:14:47 · 1291 阅读 · 0 评论 -
递推(c++)
与递归相反 递归是将一个问题分成若干个子问题 而递推是先求出若干个子问题 再去推出那个问题。原创 2024-09-12 21:34:38 · 499 阅读 · 0 评论 -
递归(c++)
从 1∼n1∼n 这 nn 个整数中随机选出 mm 个,输出所有可能的选择方案。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如。从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。把 1~n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序。其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。首先,同一行内的数升序排列,相邻两个数用一个空格隔开。按照从小到大的顺序输出所有方案,每行 11 个。按照从小到大的顺序输出所有方案,每行1个。原创 2024-09-11 22:28:41 · 601 阅读 · 0 评论 -
DFS与BFS
DFS即Depth First Search,深度优先搜索。简单地理解为一条路走到黑。以该图为例:先走A,然后到B,到了B有三种情况,意味着这条路还没走完,那我就接着走,从B走到E,走到E之后没路了。那我就回溯到B,为什么呢?因为我原本走到B的时候就有三种情况,但是刚刚只走了一种情况,因此我要回到B再去尝试第二条路,于是我们就从E回到B,然后从B去F。到了F,又没路了,那我们就回到B走第三种情况,从B到G。这样我们就走完了从A->B的三种情况。原创 2024-08-24 23:06:57 · 1680 阅读 · 0 评论 -
Dijkstra(c++)
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。同时dijkstra算法主要用于解决单源最短路问题(边权为正数),其可以分为两种版本,两种版本各有用处,并不存在好坏之分,接下来我们用n代表点的数量,用m代表边的数量。原创 2024-08-24 16:18:08 · 935 阅读 · 0 评论 -
c++拓扑排序
图的拓扑序列是针对有向图来说的 无向图没有拓扑序列若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个拓扑序列。举个例子:在下图中有一个序列 在该序列中 1 2 3为一个拓扑序列因为在(1,2)中 1在2前面 (1,3)中 1在3前面 (2,3)中 2在3前面所以成立并不是每个序列都有拓扑序列举个例子:如下图所示 如果存在环 一定没有拓扑序列有向无环图又被称为拓扑图在这里在介绍两个概念 : 入度和出度。原创 2024-08-23 22:27:47 · 374 阅读 · 0 评论 -
树与图的宽度优先遍历
大致思想请参照该篇博客主要地方的差异就是:宽度优先遍历就是一层一层的搜索。原创 2024-08-23 22:25:52 · 384 阅读 · 0 评论 -
树与图的深度优先遍历
重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。接下来 n−1 行,每行包含两个整数 a 和 b,表示点 a 和点 b 之间存在一条边。请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值。1、邻接矩阵 g[a,b] 存储 a -> b这条边的信息。有向图(边是有方向的: a -> b);无向图(边是无方向的 : a - b )原创 2024-08-22 21:48:44 · 412 阅读 · 0 评论 -
BFS宽度优先搜索
适用于处理的问题 只有当边权都一样的时候(比如边权都是1)才可以使用BFSBFS即Breadth First Search,即广度优先搜索。如果说DFS是一条路走到黑的话,BFS就完全相反了。BFS会在每个岔路口都各向前走一步。因此其遍历顺序如下图所示:我们发现每次搜索的位置都是距离当前节点最近的点。因此,BFS是具有最短路的性质的。为什么呢?这就类似于我们后面要学习的贪心策略。这里简单地介绍一下贪心,假设我们可以做出12次选择。我们想得到一个最好的方案。原创 2024-08-21 16:53:31 · 510 阅读 · 0 评论 -
位运算与常用库函数
返回去重之后的尾迭代器(或指针),仍然为前闭后开,即这个迭代器是去重之后末尾元素的下一个位置。该函数常用于离散化,利用迭代器(或指针)的减法,可计算出去重后的元素个数。upper_bound 的用法和lower_bound大致相同,唯一的区别是查找第一个大于x的元素。lower_bound 的第三个参数传入一个元素x,在两个迭代器(指针)指定的部分上执行二分查找,返回指向第一个大于等于x的元素的位置的迭代器(指针)。翻转一个数组,元素存放在下标1~n: 左开右闭,左边的数字可以取到,右边的取不到。原创 2024-08-20 19:41:15 · 497 阅读 · 0 评论 -
c++ stl库
所有的容器都可以视作一个“前闭后开”的结构,end函数返回vector的尾部,即第n个元素再往后的“边界”。set和multiset的迭代器称为“双向访问迭代器”,不支持“随机访问”,支持星号(*)解除引用,仅支持”++”和–“两个与算术相关的操作。设x是一个元素,s.erase(x) 从s中删除所有等于x的元素,时间复杂度为O(k+logn),其中k是被删除的元素个数。 s.count(x) 返回集合s中等于x的元素个数,时间复杂度为 O(k +logn),其中k为元素x的个数。原创 2024-08-20 19:40:23 · 820 阅读 · 0 评论 -
acwing排列数字
在字典中,单词是按照首字母在字母表中的顺序进行排列的,比如 alpha 在 beta 之前。而第一个字母相同时,会去比较两个单词的第二个字母在字母表中的顺序,比如 account 在 advanced 之前,以此类推。字典序(dictionary order),又称 字母序(alphabetical order),含义是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。现在,请你按照字典序将所有的排列方法输出。原创 2024-08-18 23:52:13 · 328 阅读 · 0 评论 -
DFS深度优先搜索
DFS即Depth First Search,深度优先搜索。简单地理解为一条路走到黑。以该图为例:先走A,然后到B,到了B有三种情况,意味着这条路还没走完,那我就接着走,从B走到E,走到E之后没路了。那我就回溯到B,为什么呢?因为我原本走到B的时候就有三种情况,但是刚刚只走了一种情况,因此我要回到B再去尝试第二条路,于是我们就从E回到B,然后从B去F。到了F,又没路了,那我们就回到B走第三种情况,从B到G。这样我们就走完了从A->B的三种情况。原创 2024-08-12 23:41:28 · 717 阅读 · 0 评论 -
c++ stl库
begin()/end() vecotr的第0个数 即a[0] /vector的最后一个数的后面一个数 即a[size]push_back()/pop_back() 向vector的最后插入一个数/把vector最后一位数删除。 push_back()/pop_back() 向最后插入一个元素 /弹出最后一个元素。 不支持 lower_bound()/upper_bound(), 迭代器的++,–front()/back() 返回第一个数/返回最后一个数。原创 2024-08-11 23:09:41 · 315 阅读 · 0 评论 -
用数组实现堆(c++)
堆是一种叫做完全二叉树的数据结构,完全二叉树 :除了最后一层之外,上面全部都是满的,最后一层也是从左往右排列的heap表示正整个堆 size表示当前堆的大小1、插入一个数x//在堆的最底层插入一个数字x//然后将x不断上移up(size);2、求集合当中的最小值heap[1];3、删除最小值//先用最后一个点覆盖掉第一个点//然后把最后一个点删除size --;//最后让1号点往下走down(1);4、删除任意一个元素k跟删除最小值类似size --;原创 2024-08-10 23:55:51 · 378 阅读 · 0 评论 -
用数组模拟栈和队列
共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 − 1。给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 − 1。也就是说栈里面的数 不能大于新插入的元素。第二行包含 N 个整数,表示整数数列。第一行包含整数 N ,表示数列长度。先进先出:队尾插入元素,队头弹出元素。1≤数列中元素≤10^9。原创 2024-08-10 23:53:58 · 208 阅读 · 0 评论 -
并查集(c++)
对于每个询问指令Q a b,都要输出一个结果,如果 a和 b 在同一集合内,则输出 Yes,否则输出 No。每个集合都用一棵树来表示,树根的编号就是整个集合的编号。,将编号为 a 和 b 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;3、对于集合中的每一个点 都去存储他的父节点是谁 p[x] 是指x节点的父节点是谁。//假设想合并的第一个集合里面有1000个元素,第二个集合里面有2000个元素。//要么是将第一个集合中属于的那个编号改成第二个集合中的子编号,要么换一下,原创 2024-08-09 12:13:03 · 487 阅读 · 0 评论 -
trie算法
高效的存储和查找字符串集合的数据结构它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高son[N][26]下标是x的点x这个节点的所有的儿子是去存储到son[x][26]里面son[x][0]就是第一个节点 son[x][1]就是第二个节点cont[x]表示以x为结尾的单词有多少个// 0号点既是根节点,又是空节点// son[][]存储树中每个节点的子节点// cnt[]存储以每个节点结尾的单词数量。原创 2024-08-08 22:08:09 · 463 阅读 · 0 评论 -
kmp算法(c++)
以i为终点的后缀和从1开始的前缀相等,并且保证后缀的长度最长//p数组中从1到j这一段与 从i-j+1到i这一段相等当上面数组移动到S[i] 下面移动到p[j + 1]的时候,s[i]!= p[j+1]此时就要将 红颜色的线从前往后移动 要计算的是 从前往后最少需要移动多少 直接调用next[j]移动完成之后 就变成第三段线段 从原本的j变成next[j]然后就继续比较next[j]下面一位跟s[i]最终就一直递归上面的操作 直到完全匹配为止。原创 2024-08-07 17:27:15 · 2004 阅读 · 0 评论 -
用数组表达双链表
在这里没有定义head,直接让0号点是head,下标为1的点是最右边的//e[i] 表示节点i的值为多少//l[i] 表示节点i指向左边的指针//r[i] 表示节点i的指向右边的指针//idx 相当于一个指针 表示当前已经用到了哪个点。原创 2024-08-06 23:13:53 · 406 阅读 · 0 评论 -
用数组处理单链表(c++)
/head 表示头节点的下标//e[i] 表示节点i的值为多少//ne[i] 表示节点i的next指针是多少//idx 相当于一个指针 表示当前已经用到了哪个点。原创 2024-08-06 00:46:38 · 536 阅读 · 0 评论 -
lowbit(x)
返回x的最右边的一位1以及后面的所有数一个整数的负数是补码(取反+1)原创 2024-08-05 00:02:15 · 275 阅读 · 0 评论 -
简单的位运算
1、先把第k位移到最后一位 n >> k (把n的第k位数字移动到个位)a<<b 表示把a转为二进制后左移b位(在后面添加 b个0)。n&1:与操作,判断 n 二进制最右一位是否为 1。2、看个位是多少 x & 1 (x的个位是 )a>>b表示二进制右移b位(去掉末b位)。n&1常用来判断n是奇数还是偶数。n的二进制 表示中 第k位是多少。原创 2024-08-04 23:56:36 · 173 阅读 · 0 评论 -
双指针算法
双指针算法的作用就是为了上面的朴素算法的时间复杂度优化到O(n)给定一串字符,每段字符之间可能会有空格,以空格为会车点输出结果。正常做题的时候一般都会使用两个for循环来解决问题。1、两个区间的双指针。2、一个区间的双指针。原创 2024-08-04 22:34:11 · 285 阅读 · 0 评论 -
整数二分(c++)
即可以看做成找数字那个游戏在一百个数字中找到指定的数字(66)A出题 B:50A 50太小了 B : (50+100)/2 = 75A 75太大了 B :(50 + 75) /2 = 62所以也可以知道一个结论 :有单调性,一定可以二分。可以二分的题目,不一定有单调性。a[]数组 1 2 2 2 3 3 4 4 5 找到最后一个2check (mid) 是指一个判断 a[mid] <= 2 (要找的数)原创 2024-08-03 18:53:15 · 404 阅读 · 0 评论 -
高精度加法、减法、乘法、除法(C++)
首先是定义输入的两个数字,在这里采用vector储存两个加数是为了能够动态的存储数字,并将他们的顺序逆过来(逆过来是为了让他们从个位开始相加)。然后调用add方法(该方法是一个模板),首先设置一个数组(去储存两数相加的结果)和一个变量(表示两个数字相加的进位),对每一位的数字进行加法运算。原创 2024-07-29 19:50:49 · 826 阅读 · 0 评论 -
二维差分(c++)
输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。假定a[i][j] = 0,那么b[i][j] =0,然后读取数组a,只需要对b进行插入即可。b[i][j]相当于从(i,j)到(i,j)插入一个a[i][j]形成的。即a[i][j]存的是[i,j]左上角所有b[i][j]的和。将a[i][j]表示为一个差分数列b[i][j]的和。原创 2024-08-01 16:36:56 · 647 阅读 · 0 评论 -
高精度减法
【代码】高精度减法。原创 2024-07-29 23:41:42 · 312 阅读 · 0 评论 -
二维前缀和的计算(c++)
输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1, y1, x2, y2,表示一个子矩阵的左上角坐标和右下角坐标。接下来q行,每行包含四个整数x1, y1, x2, y2,表示一组询问。接下来n行,每行包含m个整数,表示整数矩阵。对于每个询问输出子矩阵中所有数的和。−1000≤矩阵内元素的值≤1000。共q行,每行输出一个询问的结果。第一行包含三个整数n,m,q。原创 2024-08-01 00:05:17 · 717 阅读 · 0 评论 -
一维前缀和
原i a1.a2,a3,a4,a5,a6 …. an前缀和 Si = a1+ a2 +a3 … + ai (注:要从下标为1开始, S0定义为0)原创 2024-07-31 21:48:42 · 525 阅读 · 0 评论 -
高精度除法(C++)
【代码】高精度除法(C++)原创 2024-07-30 19:35:45 · 555 阅读 · 0 评论 -
差分算法及代码模版(c++)
b[n],因此只需要将b[l] = b[l] + c 即可,这样l之后的数字会依次加上常数c,而在 b[r]处,将b[r+1] = b[r+1] - c ,这样r之后的数组又会恢复原值,仅需要处理这两个边界的差分数组即可,时间复杂度大大降低。b[i][j]相当于从(i,j)到(i,j)插入一个a[i][j]形成的。构造方式为b[1] = a[1], b[2] = a[2] - a[1], b[n] = a[n] - a[n-1];即a[i][j]存的是[i,j]左上角所有b[i][j]的和。原创 2024-08-01 16:39:27 · 1440 阅读 · 0 评论 -
c语言基本的排序算法
q[l] q[ (l+r)/2 ] q[r] 随机。所有小于等于x 的在左半边。所有大于等于x 的在右半边。原创 2024-07-21 20:04:16 · 259 阅读 · 0 评论 -
一维差分(c++)
b[n],因此只需要将b[l] = b[l] + c 即可,这样l之后的数字会依次加上常数c,而在 b[r]处,将b[r+1] = b[r+1] - c ,这样r之后的数组又会恢复原值,仅需要处理这两个边界的差分数组即可,时间复杂度大大降低。b[n]为差分数组。目的就是为了推导出b[1] = a[1], b[2] = a[2] - a[1], b[n] = a[n] - a[n-1];构造方式为b[1] = a[1], b[2] = a[2] - a[1], b[n] = a[n] - a[n-1];原创 2024-08-01 09:40:35 · 525 阅读 · 0 评论
分享