算法与数据结构
算法与数据结构
sher lock
这个作者很懒,什么都没留下…
展开
-
Dijkstra算法
总体思路代码朴素算法总体思路S:当前已经确定起点到它的最短距离的点的集合1.初始化距离,用数组,起点为第一个点,那么dist[1]=0,其他的距离设置一个非常大的数。2 for 从1~n这是一个迭代的过程,每一次确定一个点到起点的最短路,确定的点的当前还没有确定的点中距离最小的点(贪心的思想)2.1找到t这个点,并把t加入到S中t:不在S中,能找到的到起点距离最短的点,把它加入到S中,(因为你的S已经是确定好最短路的点了,然后呢你的t又刚好是从这个点出发的直接接触到的最短的点了,所以.原创 2022-02-21 15:25:04 · 169 阅读 · 0 评论 -
并查集模板
并查集用于:1.合并两个集合2.查询两个元素是否在一个集合中#include <iostream>using namespace std;const int N = 100010;int p[N];int find(int x){ if (p[x] != x) p[x] = find(p[x]); return p[x];}int main(){ int n, m; scanf("%d%d", &n, &m);原创 2021-11-29 21:37:05 · 179 阅读 · 0 评论 -
c++ stl
STLvectorfindstringfind从头开始查找从固定位置开始查找substrSTLvectorfind vector<string> m; m.push_back("hello"); m.push_back("hello2"); m.push_back("hello3"); if (find(m.begin(), m.end(), "hello") == m.end()) cout << "no" <<.原创 2021-10-19 00:20:22 · 131 阅读 · 0 评论 -
kmp算法
next数组代码next数组next数组是关于你的目标串的例如目标串如下next[1]代表前一个元素组成的串,最长的前缀和后缀相等的长度是多少,next[1]=0next[2]=0next[3]代表前三个元素组成的串,最长的前缀和后缀相等的长度是多少next[3]=1next[4]=2next[5]=3next[6]=4next[7]=5next[8]=6代码#include<iostream>using namespace std;const int .原创 2021-10-14 00:54:41 · 70 阅读 · 0 评论 -
L2-038 病毒溯源 (25 分)
思路代码看懂别人的做法是一回事,自己会做又是另一回事。别人的做法再优雅,不是你的风格。对你也无用。只有你自己独立做出来的题目。用你自己总结出的体系去做出来的解法。充满你自己风格的解法。才是你真正的东西。思路1.先建好树2.正常dfs遍历3.你一开始设置maxdeep = 1最后又return maxdeep 其实你已经安顿好了你的叶子结点。嗯安顿好你的叶子结点是dfs中最重要的事情。4.因为你已经安顿好了,于是你调用自己求出这个子树的深度。5.如果儿子的深度 + 1大于最大的深度maxd.原创 2022-04-23 10:18:25 · 204 阅读 · 0 评论 -
L2-011 玩转二叉树(建树+BFS)
《非常简单的一道题目》就,如果你懂得关于树的知识,那么就确实就是很简单。题目都没有很难的,你觉得难是因为你的知识点不熟练。 建树层序遍历(用bfs)满分代码#include<bits/stdc++.h>using namespace std;const int N = 1e2+10;int in[N],pre[N],n;struct Node{ int l,r;}Tree[N];int build(int l1,int r1,int l2,int r2){//l1原创 2022-04-22 17:19:56 · 1636 阅读 · 1 评论 -
差分的算法
点点插入函数()一开始需要insert(i,i,a[i])还原b[i]+=b[i-1]#include <iostream>using namespace std;const int N = 100010;int n, m;int a[N], b[N];void insert(int l, int r, int c){ b[l] += c; b[r + 1] -= c;}int main(){ scanf("%d%d", &am.原创 2022-04-08 23:47:28 · 500 阅读 · 0 评论 -
快速幂算法
错误总结错误总结没思路先把res初始化好就来安排你这个b如果是奇数一行安排,就处理res就好了,如果是偶数就处理两个,一个是a 一个是b#include <iostream>#include <algorithm>using namespace std;typedef long long LL;LL qmi(int a, int b, int p){ LL res = 1 % p; while (b) { if .原创 2022-04-08 21:38:53 · 314 阅读 · 0 评论 -
蓝桥杯做题顺序
蓝桥杯的做题顺序应该是一个贪心的策略。每次都花最少的时间得到你会做的分数。先做填空前两道题目再做大题前两道题目再做大题后面所有题目的暴力再看下填空题会哪些题目做一下再研究大题你的暴力解法怎么优化...原创 2022-04-07 11:29:22 · 504 阅读 · 0 评论 -
分解质因数
for(int i=2;i*i<=x;i++)·最后最多剩下一个大于sqrt(x)的质因子,看一下有没有,如果有的话,那再加上就好了。就正常算质因子,算到一个了之后把这个的所有个数求出来。最后如果x>1最后还有一个的话,那就再输出这最后一个。#include <iostream>#include <algorithm>using namespace std;void divide(int x){ for (int i = 2; i * i &l原创 2022-04-07 11:26:30 · 255 阅读 · 0 评论 -
bfs 广度优先搜索
bfs问题,你的起点和终点是要自己找的啊啊啊啊bfs问题,如果是迷宫问题,那么你bfs函数的两个参数是pii start 和pii end是不错的选择,然后距离用dist[N][N]就是更不错的选择原创 2022-04-06 09:24:52 · 79 阅读 · 0 评论 -
最长上升子序列
要再注意一下你状态转换的条件,必须满足一定条件,你的状态才能够转换过去的。不要无脑转换,在乎一下你什么时候才能够转移过去。还是要多注意一下题目,按具体题目的意思来做。#include <iostream>#include <algorithm>using namespace std;const int N = 1010;int n;int a[N];int f[N];int main(){ cin >> n ; for (in.原创 2022-04-04 22:34:41 · 195 阅读 · 0 评论 -
动态规划 y式dp分析法
如果你的状态表示式子中出现了i-1这种东西的话。那你的下标就要从1开始了。原创 2022-04-03 22:27:22 · 444 阅读 · 0 评论 -
floyd算法
初始化: for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) if (i == j) d[i][j] = 0; else d[i][j] = INF;// 算法结束后,d[a][b]表示a到b的最短距离void floyd(){ for (int k = 1; k <= n; k ++ ) for (int i =原创 2022-04-02 22:10:40 · 351 阅读 · 0 评论 -
用邻接表dfs和bfs图
dfsbfs树是一种特殊的图,与图的存储方式相同。 对于无向图中的边ab,存储两条有向边a->b, b->a。 因此我们可以只考虑有向图的存储。(1) 邻接矩阵:g[a][b] 存储边a->b(2) 邻接表:// 对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点int h[N], e[N], ne[N], idx;// 添加一条边a->bvoid add(int a, int b){ e[idx] = b, ne[id.原创 2022-04-02 21:27:58 · 787 阅读 · 0 评论 -
求树的高度和深度
就你dfs的顺序还有维护的东西这两个东西你需要再次理解清楚一下。dfs就是dfs,一定要清楚dfs执行的顺序。深度就是父亲的深度+1这没什么好说的。但是高度。是所有儿子结点的最大高度+1。这个点其实是有点像dp的,从最小的一层开始。一直往上运算。#include<bits/stdc++.h>using namespace std;const int N = 1e5+10;vector<int> v[N];int n;int shen[N];int gao[N原创 2022-04-01 22:19:44 · 335 阅读 · 0 评论 -
蓝桥杯 对于日期的问题
一个年份满足以下条件之一则是闰年:1、该年份能被4整除,但不能被100整除;2、该年份能被400整除;给你一个日期,知道这一天是星期几,然后再给你一个日期,问你这一天又是星期几。关键步骤就是那个mon数组啊,你就设置成int mon[2][13] = {0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};然后问题就迎刃而解了。已知1900年1月1日是星期一#include<.原创 2022-04-01 16:51:24 · 509 阅读 · 0 评论 -
最长公共子串 暴力
#include<bits/stdc++.h>using namespace std;int tn;int t;string a,b;int main(){ cin>>t; getchar(); while(t--){ cin>>a>>b; string t; string ts,ta; tn = 0; for(int k=1;k<=a原创 2022-04-01 16:29:57 · 407 阅读 · 0 评论 -
L1 - 8 饱了吗公司 (20 分) dfs 或者 并查集
就是你考试的时候把并查集代码背错了导致你被迫去写了这个代码,但是也是好事,你现在对于dfs的理解可谓是真正地加深了许多。思路每个点,进一个点就res++。然后把所有邻接的点都加进来,所以最后res是几就代表有几块。遍历图就是很重要的一点就是,再每次dfs之前需要去判断一下的。如果是没走过这个点你才去走,要不然因为是无向图,会导致不断你进我,我进你,一直走不出去的情况。#include<bits/stdc++.h>using namespace std;const int N =原创 2022-03-26 16:46:47 · 567 阅读 · 0 评论 -
L2-2-链表 重排链表 (25 分)
这个思路是真的好,比别人的思路都好太多了,用一个l索引和r索引,一个arr1数组和arr2数组,巧妙地化解了这个问题。#include <iostream>using namespace std;typedef struct Node{ int a; int nt;}Node;int main(){ Node p[100001]; int ad,n,address,m,next,cnt,l,r,x; int arr1[100001原创 2022-03-23 11:02:42 · 970 阅读 · 0 评论 -
L2-3-深度优先搜索 图着色问题 (25 分)
图的遍历用二维vector邻接表存图,所谓邻接就是把相邻的点存到以这个序号为下标的vector里面然后要记得,你题目这边都给出来了,就是说你的结点的编号是从1到v的,所以你遍历的时候第一层就用1到v就好了。要记得你循环跳出的条件#include<bits/stdc++.h>using namespace std;int v,e,k;const int N = 510;int color[N];vector<int> g[N];bool check(){原创 2022-03-22 22:35:20 · 297 阅读 · 0 评论 -
L1-3-嵌套循环 / if-else 阅览室 (20 分)
时隔多年,也是终于纯纯靠自己写出来了,这种感觉确实是比当初背代码的感觉要好一些。哎,还是得要纯纯地靠自己思考下刷题才是有效的啊。#include<bits/stdc++.h>using namespace std;const int N = 1e3+10;struct shu{ int time; int st; }shus[N];struct day{ int cnt; int total; int pj;}days[20];原创 2022-03-22 21:35:00 · 135 阅读 · 0 评论 -
L1-6-while和do-while 整除光棍 (20 分)
就是纯纯模拟竖式除法的一道题目#include<bits/stdc++.h>using namespace std;int main(){ long long n; cin>>n; int res = 1; int cnt = 0; while(res<n){ res = res * 10+1; cnt++; } while(1){ if(res%n =原创 2022-03-22 20:21:25 · 311 阅读 · 0 评论 -
树状数组(可以修改的前缀和)
前缀和呢,其实也是完全可以看成是可以求一段区间很好求的东西。其中有且只有3个很简单的函数lowbit函数,求x的二进制表达式中最低位的的1所对应的值x&(-x)add函数,参数有2个,x,v表示第x个数加上v循环,从这个数到最后一个数,tr[i] += v注意,add函数的循环和query函数的循环每一步的幅度都是lowbit(i)query函数,参数就1个x,表示前x个数相加的和循环,i = x到i(i>0)变小的循环,res += tr[i]#include <c原创 2022-03-22 15:11:37 · 217 阅读 · 0 评论 -
L1-8 字符串拆分 (20 分) dfs 对于判断结构的bool型dfs
就对于这种dfs:flag = flag||dfs(...)是一个很好用很常见的结构需要注意剪枝,如果说不会大于long long 那么大于1e11就可以返回false了复现遇到的问题:1.你的len忘记初始化了,忘记每次都给它初始化了。#include<bits/stdc++.h>using namespace std;typedef long long ll;int len;bool dfs(string s, ll pre, ll cur, int i..原创 2022-03-20 21:07:31 · 1005 阅读 · 0 评论 -
不能交换相邻的两个
这个限制呢,只能限制个数为1,2,3的情况1,2原封输出3的话就2不变,13交换顺序就好了。(可以使用给2一个很大的权重这种方法,然后排序,之后按照2,1,3的顺序输出就好了(因为你2的权重很大,所以你2会在第一个位置,然后你给它放到第二个输出就好了))然后对于个数大于等于4的话,这个限制就毫无影响如果只有一个人,直接输出就可如果只有两个人,两个人无法交换,直接输出就可如果只有三个人,第二的人的位置无法变动,对第一第二个人进行排序,保持第二个人不动即可如果是四个人即以上可以证明这个限制没有影原创 2022-03-19 21:27:40 · 121 阅读 · 0 评论 -
501B - Misha and Changing Handles
只能说这题体现了map的能力很强大#include<bits/stdc++.h>using namespace std;const int N = 1010;int main(){ map<string,string> m; int n; cin>>n; string a,b; while(n--){ cin>>a>>b; if(m.count(a)==0){ m[a] = a; } m[b] =原创 2022-03-13 19:01:04 · 233 阅读 · 0 评论 -
L2-4-深度优先搜索 功夫传人 (25 分)
感动啊,时隔多年,我终于会dfs了!!这道题当初背代码背得很难受,当初觉得真的是很难的一道题目,一直背代码,改代码,始终不得要领。现在终于会做了,知道这道题目的每一个注意点是什么了,我都很清楚,也算是真正理解并且熟练运用了dfs你会发现一道题目,其实写的东西,代码量并不多,你读入数据就会占据很大一部分代码量,其实你自己写的不多dfs呢,你进形参的东西的其实就是你需要带进这个旅途的东西,就是会根据你的每一层会不断变化的东西。然后你放进形参中托管。如果一个东西它不会随着你每一层的进进出出而变化,那么你就原创 2022-03-13 16:01:38 · 844 阅读 · 0 评论 -
素数筛法(线性和埃式)
埃式筛法:每个数字筛的时候都把它的倍数都筛掉const int N= 1000010;int primes[N], cnt;bool st[N];void get_primes(int n){ for (int i = 2; i <= n; i ++ ) { if (st[i]) continue; primes[cnt ++ ] = i; for (int j = i + i; j <= n; j += i)原创 2022-03-12 21:54:19 · 226 阅读 · 0 评论 -
c++分割字符串(空格)
vector<string> split(string str) { int size = str.size(); vector<string> ret; int jl = 0; for (int i = 0; i < size; i++) { if (str[i] == ' ') { ret.push_back(str.substr(jl, i - jl)); jl = i+1; } } ret.push_bac原创 2022-03-12 17:22:22 · 5718 阅读 · 2 评论 -
codeforces 1598 A
做这题的时候是真的感觉到自己被耍了。原本想要练习一下dfs来到了codeforces寻找dfs的题目,然后发现了这题看起来很简单,就是以前做过的迷宫,然后直接dfs就开始做了。最终写了一大堆东西写出了这个dfs,超时掉了。然后我也不知道这个是错的还是对的,可能是对的吧,写得这么工整。哎,虽然思路错掉了但是这也算是我第一次思路清晰地写出来dfs。#include<bits/stdc++.h>using namespace std;int dx[8] = {-1,-1,0,1,1,1,0原创 2022-03-11 16:46:01 · 122 阅读 · 0 评论 -
二叉树的遍历序列
给你二叉树的后序遍历,让你弄出它的层序遍历。就说实话,你的学习资料的优质与否对你的影响是天差地别的,之前我看了老师的答案,垃圾得一批,搞得我以为很难,一直不敢做。现在看了柳婼的代码,确实好啊。首先明确一点,如果你把二叉树看成是一个一维数组,那么你的层序遍历就是按照顺序去走一边你的数组,后序遍历就是按照idx*2,idx*2+1,idx的递归顺序去走一遍。在递归之中模拟后序遍历的过程,在后序遍历时,传递的是你后序遍历时候的下标按照这个下标的顺序去把后序遍历的内容填进来#include <b原创 2022-03-09 09:28:58 · 1249 阅读 · 0 评论 -
判断是否是一个小根堆
就是递归地判断,函数里面一个是当前结点,另一个是父结点然后你从当前结点,第一层开始遍历:取出你拿到的结点如果这个结点就是你的父结点的话就continue(防止输入的时候有问题)如果这个结点的值小于你的父结点的话,那就代表不是一个小根堆然后开始递归,把当前结点当作父结点,这个结点当作来弄的结点如果不是的话返回false;不然如果for循环结束还没有false的话,返回true递归其实确实很妙,就是需要它的每一层的结构,都和上一层是完全一样的。bool check_mi(int u, int原创 2022-03-08 17:13:13 · 1118 阅读 · 0 评论 -
L1-7 前世档案 (20 分)
看到极其强烈的二叉树的形状,就得要往二叉树的方式去想,去靠左子树2x右子树2x+1这你学到的东西要用起来啊。这题是我没想到的,当时我在天梯做的时候想出了一个自以为很好的做法,然后得了大部分的分数,当时感觉自己已经可以了。时隔多年之后再次回来做这道题,没想到我这些年来都是在瞎做,根本没有入门。拿到一个问题,首先需要考虑的是考点啊,考虑的是你学到的东西拿来用啊,你看不到前路很正常,看不到一步一步的清晰的结果很正常,但是你看出了他考察的知识点,你就先按照这个知识点的固定写法去写出来,写出来看看,然后走原创 2022-03-05 16:13:58 · 516 阅读 · 0 评论 -
蓝桥杯递推
点:1)就是你做的时候不要想当然,要尽量去模拟好,它怎么样的你就怎么样去弄噢,一步一步来,没事稳一点原创 2022-02-23 16:46:01 · 119 阅读 · 0 评论 -
递归dfs
递归呢,也可以叫做dfs1.最重要的是考虑出一个顺序可以不重不漏地把所有的方案找出来2.考虑循环退出的条件3.你的父节点对每一个子结点都需要公平(恢复现场)牛逼🐂原创 2022-02-23 15:16:48 · 668 阅读 · 0 评论 -
常见2的次方结果总结
2的15次方327682的16次方655362的20次方一百万2的63次方1e18原创 2022-02-23 14:54:35 · 1082 阅读 · 0 评论 -
L2-4 你才菜到家了 (25 分)
点点1.按字典序最小的顺序排列合起来的字符串的字典序最小,显然2.就你判断它到底能不能生成一个最小生成树,你有两种方法(1)加一次边就cnt++,到最后如果cnt<n-1,就代表是不可以生成最小生成树(n是总点数)(2)从头到尾用find函数再次找一下父亲结点,如果父亲结点等于本身的结点不止一个,那么就不能生成一个最小生成树。因为你一个最小生成树就只有一个根结点。...原创 2022-02-23 10:52:43 · 667 阅读 · 0 评论 -
kruskal算法
思路思路1.将所有边从小到大排序2.按从小到大的顺序枚举每条边a,b(权重c),如果当前a,b不连通,就把这条边加入到集合里面中原创 2022-02-22 19:55:36 · 338 阅读 · 0 评论 -
L2-3 菜到家了
把bool数组都初始化为falsebool A={0};原创 2022-02-22 11:39:58 · 308 阅读 · 0 评论