- 博客(65)
- 收藏
- 关注
原创 [刷题之旅no44]排序
一个数组a,大小n一个k保证k<=n且a[i]<=k;来一个时间复杂度为O(n)的排序算法思路:就是开一个大小为k的数组b初始化遍历数组a,记录相应大小值的出现次数遍历b,覆盖a结束void sort(int a[],int n,int k)//将a中元素递增排序{ // 请在这里补充代码,完成本关任务 /********** Begin *********/ int b[k+1]; for(int i=0;i<=k;i++)
2021-04-09 21:30:01
121
原创 [刷题之旅no41]利用栈和队列判断回文数
众所周知栈是后进先出队列为先进后出所以把字符串输入到队列和栈之中然后每次出队和出栈,如果相等,继续出队和出栈到len/2+1的时候,直接说明全对即可int isPalindrome(char *str)//判断字符串str是否回文,是则返回1,否则返回0{/**********begin**********/ TWSTACK stack; QUEUE queue; inistack(stack); iniQueue(queue); int i=0;
2021-04-09 20:08:51
340
原创 [刷题之旅no40]P3369 【模板】普通平衡树&&[数据结构no4]splay树
嗯。。。看到题目之后,我就觉得应该直接看题解了,别怪我,我连数据结构也没学呢题解也看不懂哦看到大佬的题解:我看到了:SplayTreapen…那就先学splay,再学treap吧!(但是我估计我学了splay之后就没心思学treap了),...
2021-04-05 13:57:31
130
原创 [刷题之旅no39]P1983 [NOIP2013 普及组] 车站分级
好的朋友们这道题,很简单求车站的分级一旦涉及到这种级别,优先级,你要干什么,就必须先干什么的这类话都可以通过建图,拓扑排序来找到答案!数据结构:1.链式前向星,一共可能有十万条边1.读取车站个数,一共有多少次车次2.循环m次,每次读取车次,读完车次前向星建边,记录每个点的入度,就是建边的时候++;3.遍历找到入读为0的点,全部入队,设置head,tail,tallast4.循环(队列不是空){判断是否时空队列看队首元素遍历所连点所连点入度减一如果入度为0那么直接入队(移动t
2021-04-04 19:26:45
214
原创 [算法学习no17]拓扑排序
拓扑排序就是给你一个有向图让你按照点的优先级来输出点的一种排序算法到底什么是点的优先级呢?比如说,在这个图中,a结点指向b结点,那我们就可以说a的优先级比b高。所以我问问你,优先级最高的结点有什么特点?当然,就是没人指向它,即入度为0的点那我再问问你,优先级第二高的结点有什么特点?哈哈,不是优先级最高结点指向的结点就是第二高结点哦优先级第二高的结点,就是在你把优先级第一高的结点移走之后(同时把他们的边也移走)剩下这张图中的最高级结点,也就是移走一级节点之后入度就变成0的那些结点同理,我
2021-04-04 19:26:40
71
原创 [刷题之旅no38]P1381 单词背诵
具体代码就不放出来了,毕竟是一个连数据结构课都还没学的大一萌新,只是在这里分享一下我的思路,一个初学者的小想法。步骤:1.读取n,循环读取字符串2.把每个读到的字符串用哈希求出一个具体的数值(具体怎么求之后说),并且按顺序存入到一个名字叫dictionary的数组之中。3.对dictionary排序(升降无所谓)4.读取m,循环读取字符串5.把每个读取到的字符串用哈希算出一个值6.在我们已经排好序的dictionary的数组里面找到他的下标(即编号)7.进行入队等一系列操作(之后再说,重点)
2021-04-04 13:56:34
169
原创 [数据结构no3]二叉堆
二叉堆,就是一个完全二叉树似的东西每个结点的子节点都必须大于或者小于或等于其父节点(堆序性)储存结构:数据规律:每个结点为i,则其子节点的编号为2i和2i+1;用于高效率维护一个排序好的队列,保证我们无论是删除还是插入都能够高效进行注意要先排序再维护,对象为一个已经有序的数列插入操作:(以升序列为例)1.取数组最后一个空的下标2.找出这个下标的父节点3.判断这个父节点是否小于等于我们当前的结点4.不小于,则把这个父节点移动到当前位置5.更新下标拨针为i=i/2;继续比较6.如果i
2021-04-04 09:19:46
66
原创 [刷题之旅no37]合并果子
给数组大小给数组元素每次找出两个数求和,把求和的元素放回数组里面,累计求和值直到数组里面只剩下一个值位置,求求和值的最小值看到这道题,看到贪心的标签,我假设用贪心算法可以解决只需要每次计算找出整个数组中的最小的两个元素就好了那么就要涉及到排序当然也可能涉及到维护。反正我只需要保证我每次都能取出当前队列中最小的那两个元素就行其它倒是不用操心现在只需要思考如何维护队列的大小就好了已知至多有1万个元素,那么我们这样做至少经过9999次运算这9999次运算对应着9999次维护我晕该如
2021-04-04 09:19:20
85
原创 [刷题之旅no36]P1309 [NOIP2011 普及组] 瑞士轮
暂时没什么好的思路,只能先试试看1.读取,读取对数,R轮数,Q最终名次2.循环2n次,读score3.循环2n次,读power4.根据score排序,将排序之后的编号存到rank数组中,rank可以直接和score合并成一个结构体4.比较函数直接进行好的思路:第一次先希尔排序因为每一次比赛都是两个人其中一个人加上一分,所以整个数组的整体顺序是没有发生太大变化的可以先用希尔吧2n拆分成两个数组进行排序,第一个数组就是13579第二个数组就是2468 10,然后用一次归并直接排先全都用希尔试
2021-04-03 21:25:57
253
原创 [刷题之旅no35]逆序对
1.归并排序思想。归并排序,就是把两个有序数对进行比较合并,变成一个有序数对如何得到两个有序数对呢?就是把两个有序数对分别再化成两个有序数对,然后再合并所以用到了递归的思想我们取其中一个状况来看,左边是从小到大的一个数列,右边是从小到大的一个数列,而当前数列中逆序对的个数如何来求呢?我们就要再归并过程中进行比较,如果左边一个元素大于右边一个元素,那么这个左边的元素的后面的所有元素就都大于右边这个元素如果左边这个元素不大于右边这个元素,那么左边这个元素也不会大于右边这个元素的所有元素,所以正常入队
2021-04-03 18:48:38
101
原创 [算法学习no16]离散化处理
什么叫离散化?比如给你一个数组下标 1 2 3数值 1 5000 2需要你进行一系列大小比较有关的操作,那么他们的实际大小就不重要了比如让你求出数组中比1大的元素个数,你知道有两个那我把5000换成 3,是不是还有2个?这个数组中5000就是最大的,如果我的操作不涉及求值,只用比较大小,就像我刚才说的,求出一个数组中比1大的元素个数那这个5000换成3 ,换成4 或者把下标为3的那个2换成3,换成4,都是不会改变的。而有的操作需要靠数值大小来确定地址,如果你的数
2021-04-03 17:37:27
248
1
原创 [算法学习no15]归并排序
归并排序就是递归+合并利用分治法把数组分成最小单元,保证每次合并都是在合并两个有序数组有序数组的合并非常高效而不断分治就是为了把数组分成单个元素,一个元素排成两个有序数组,两个有序数组排成四个有序数组等等合并有序数组的思路设置一个函数传入当前数组的前下标,和最后下标,然后利用一个空数组储存a分开之后合并的数组总结来说,归并排序就是一个递归函数只要first<last就一直保持递归,左右分支,当递归完成时,进行下面的操作,将有序数组合并即可。第一次实验失败,看看自己的归并排序到底哪
2021-04-03 16:02:23
57
原创 [数据结构no3]树状数组
顾名思义:树状的数组,利用了巧妙地数学知识首先给定一个数组arr[i]然后根据这个数组可以构造出一个平衡了查询和修改操作的数组,树状数组树状数组大小和arr[i]长度相等设树状数组为c[i]那么他代表着从arr数组中从下标为i的元素开始往前数lowbit(i)个元素的和lowbit(i)是啥呢?数学方程为lowbit(x)=x&-x;怎么理解,就是把x转化为二进制数,从右开始一个一个数,数到第一个1出现为止,然后左边的都不要了留下的数就是10000…000。这就是lowbit(x
2021-04-03 15:21:28
94
原创 [算法学习no14]进制哈希BKDR Hash
进制哈希,就是让长度为n的字符进行下列运算:for(int i=1;i<=n;i++){ans=(ans*k)+a[i];}当然这是初始版如果溢出,那么计算机会自动舍弃高位的值,留下低进制位的数字让我们现在考虑该如何选取k如果是偶数,那么最终会因为溢出而导致高位运算无法参与而如果是奇数,那么即使溢出,高位字符也会因为奇数不是2的整数倍,会留下1,从而在低位产生影响所以1.k为奇数下面我们在看看k应该选取怎么样的奇数为了自动取位,我们应该选择数据为unsigned型,如果不是这
2021-04-03 12:14:01
324
原创 [刷题之旅no34]字符串哈希
哈希表需要解决的问题:1.确定函数2.确定冲突解决办法3.选择什么样的数据结构进行存储哈希表,开辟多大的空间解决问题:1.函数的确定:如何根据一个字符串来吧函数确定出来呢?字符串很长,每个字符都有确定的ascii码值,我需要做的就是确定一个计算公式,使得给一个字符串,我可以返回一个值直接使用长度来确定感觉就很好。这样最多1500的长度,也有利于我进行操作。故:H(x)=strlen(str)2.冲突解决办法:我认为可以直接使用链地址法则,确定一个结构体,内部由一个字符串和一个next
2021-04-03 11:15:27
88
原创 [数据结构no2]哈希表
给定关键字key函数H(x)可以由f=H(key)直接算出key在数组下标中的位置,直接进行查找需要解决问题:1.选择合适H(x)提高数组空间利用率和降低冲突率2.当key1!=key2但H(key1)=H(key2)时如何解决冲突3.如何查找哈希表中特定值解决方法:对于1:如何选定函数1.直接定制:直接做线性函数2.取一定的位数:取某特定几位进行处理3.平方取中:先把这个数平方,然后取其中间某几位4.叠加和:分割成几个部分,然后求和,取特定位数5.取余:取H(key)=key m
2021-04-03 09:40:47
96
原创 [刷题之旅no33]保龄球
题目解读1.数组大小2.数组元素3.查询次数4.查询大小输出:返回下标如果查不到,直接输出0思路:1.读取数组2.排序3.二分查找结束出现了一个问题,一个逻辑错误就是题目要求我寻找对应值在原数组中的下标。那么我就需要好好思考一下了。这样吧,那么改一下数组罢了改成二维数组,当数值排序的时候,相应原数组的下标也跟着交换即可其实再加入一个数组也可以,改动还可以更少,脑子瓦特了#include<stdio.h>int arr[100005][2]={0},n,q,
2021-04-02 21:45:38
99
原创 [刷题之旅no32]P1138 第k小整数
怎么解决这个问题呢。。第一思路:直接暴力求解,用希尔排序算法,然后遍历寻找最小整数即可。1.读取2.希尔排序结束看到有大佬用桶排序和什么主席树的,列入打卡学习目标,不过暂时不需要这道题就当复习一下昨天学习的希尔排序把!代码:#include<stdio.h>int num[10005]={0},n=0,k=0;void scan(){ scanf("%d %d",&n,&k); for(int i=1;i<=n;i++) { scanf("%
2021-04-02 21:20:19
256
原创 [刷题之旅no31]P1038 [NOIP2003 提高组] 神经网络
仔细一看,仔细一想,唔是bfs。1.数据结构:1.链式前向星2.line队列3.u数组记录结点阈值4.c数组记录结点兴奋程度5.out数组用于记录最终输出结果6.队列设置三个拨针,head,tail和lasttail(lasttail用于记录上一层级结点的最后一位的下标)7.isinline数组,判断当前元素是否入队8.flag判断到底能不能兴奋思路:1.读取点的数量和边的数量2.读取点,按顺序记录点的刺激点c和阈值u,更新c和u数组值,将刺激点c大于0的点入列,同时更新tail和
2021-04-02 20:22:21
266
1
原创 [算法学习no13]prim算法
普利姆算法数据结构:1.pick数组,代表是否被选中2.mindis数组,下标就是点的编号,数值为当前已选点的集合中的所有点到这个点的距离的最小值3.father数组,下标也是点的编号,如果该点没有选定,则为-1,否则为更新mindis时对应路径和其相连的点的编号步骤:1.接入一个顶点2.遍历和这个顶点相连的所有边,拿出相连的顶点,(如果该顶点没有被选中)到mindis里面进行比较如果小于,则更新相应的mindis和father,并且和当前最小值min进行比较,如果还是小于,那么记录当前点的
2021-04-02 19:00:54
148
原创 [算法学习no12]kruskal算法
1.读取边2.对边排序3.遍历,判断当前两个点连起来之后是否成环(利用查并集)if(find(x)==find(y))4.如果成环跳过看下一位不成环那么就把这两位连起来f[find(x)]=find(y);更新dis值
2021-04-01 21:27:45
71
原创 [算法学习no11]插入排序与希尔排序
所谓希尔排序就是在插入排序外面多了一层循环并且改变了内部插入排序的间隔而已多的那层循环for(int gap=arr.length;gap>=1;gap=gap/2)把内部插入排序的间隔改成gap即可现在学习插入排序两个移动下标一个在已排序数组中a,且初始化为已排序数组中最后一个元素(即最大元素)一个指向未排序部分的第一个元素b按照从小到大排序如果b元素大于a指向元素,那么a元素前拨就好了a元素前拨方式就是arr[a+1]=arr[a],a–;直到arr[b]>=arr
2021-04-01 21:24:53
72
原创 [刷题之旅no30]P3366 【模板】最小生成树prim和kruskal
经过题意我是这样理解的就是找到n-1条边,保证1.没有闭环2.长度求和最小3.如果无法生成这个树,那么输出orz需要解决的就是这三个问题最小生成树有两个算法:prim和kruskal算法我打算都练习一下,所以还是要先学算法kruskal算法实现1.edge结构体存图bigin,end,dis2.结构体排序3.让当前两个结点连通4.判断是否闭环5.如果闭环,取消联通,继续6.如果不闭环,总路径加和问题:1.如何表示结点连通情况2.如何快速判断是否闭环问题1不用考虑问题2
2021-04-01 21:23:07
111
原创 [刷题之旅no29]P3367 【模板】并查集
这道题开一个team数组,下标就是元素序号,值为元素所在集合再开一个teamlink数组,把在一个team中的元素连起来,结尾是0;如果要查询两个元素是否在同一个集合里面,只需要查看这两个是否在一个链表里面就可以了。每次来一个元素,就连到所在team的尾端即可如何判断尾端,就是team[i]=0;就是尾端判断两个元素是否相等,就是看他们两个尾端是否是同一个元素即可20分哈哈。其余全部TLE,让我看看标准答案到底是如何处理的优化在find函数递归+路径压缩也就是在find函数设置成为递归函
2021-04-01 16:11:06
75
原创 [算法学习no10]Floyd算法以及其正确性证明
具体原理就是把图里面所有点拿出一个遍历所有路径看看能不能把这个点加入到这个路径里面也就是进行判断:dis[i,j]>dis[i,k]+dis[k,j]如果满足就要更新dis[i,j]的值完毕非常简单易于上手现在思考其正确性:如果一条路4->3->1->2->5->6为4->6的最优解.从这个图中我们可以看到,一定可以直接连通的点就是4,33,11,22,55,6Floyd算法是在把这些路都找出来,然后拼接成成品的一个过程我们已
2021-04-01 15:02:01
1074
原创 [刷题之旅no28]P2910 [USACO08OPEN]Clear And Present Danger S
1.给出结点数量,给出遍历结点数量2.给出遍历结点顺序3.给出结点之间的距离4.求解一个路径,保证路径上面有2给出的结点顺序OK现在我们来求解这个问题其实就是1.读取结点数量2.用一个数组储存遍历顺序3.用一个二维数组储存当前两个结点之间的顺序每个结点互相连通最多100个结点(有点友好啊)所以。我们只需要求解两点之间的最短路径即可。用什么方法呢?刚刚学了SPFA算法,感觉可以直接把这道题解决掉了。外层循环,遍历所有结点内层用我们的SPFA1.初始化headl,tail2.
2021-03-31 22:01:50
97
原创 [算法学习no9]SPFA
说白了就是bfs只不过,对于bfs,访问过的点不可以再访问而spfa改成了,只要你不在队列里面,就可以让你再次入队缺点:不是很稳定所以:如果被卡数据就要用dij算法(不知道全名,还没有学习)暂时写到这里...
2021-03-31 20:51:33
49
原创 [刷题之旅no27]P3371 【模板】单源最短路径(弱化版)
感觉这道题和上一道有点相似思路:数据结构:链式前向星1.读取数据。正常读取就可以了,把图构造出来2.从编号为c的点开始递归递归函数参数:node当前访问的点,从出发点到当前的点的距离dis直接标记当前结点如果dis>mindis[node]取消标记直接return,说明不是最优解其它情况,则访问和这个点相连的所有结点(访问过的结点就不要再访问了吧?)如果没有被标记,那么递归即可,dis+edge[i].dis;输出mindis[i] (i!=c);拿了40分三个TLE三
2021-03-31 20:48:38
83
原创 [刷题之旅no26]P3956 [NOIP2017 普及组] 棋盘
1.走棋盘同色直接走异色花一金无色可魔法魔法花两金不可连续魔要求最小金不同为负一思路:1.用深搜,设置参数,四个,坐标xy,是否可以使用魔法,当前金币数量根据当前位置判断可以走的方向,然后根据情况递归即可。问题:1.如何确定施加魔法的颜色2.如何执行施加魔法之后颜色消失这一步。3.如何防止重复绕圈,也就是如果我按照当前位置四个方向进行递归,肯定会出现重复路线解决问题:3.每次进入函数,将当前坐标相应位置标记为1.然后递归。当递归结束之后,把相应位置标记为0;return
2021-03-31 18:22:54
387
原创 [算法学习no7]图的遍历
图的遍历分为两种1.深度优先搜索2.广度优先搜索图的遍历难度在于图有闭环,双向所以一定不要迷路因此,需要用数组标记访问过的结点即可1.深度优先搜索传入参数为结点输出这个结点标记这个结点找到和这个结点相连的所有点判断这些点是否被访问过如果没被访问过直接递归2.广度优先搜索使用队列让传入的结点入队打印结点标记结点进入循环,终止条件为队列为空遍历和队首结点相连的所有结点如果结点未被访问那么打印结点标记结点让结点入队首元素出队二者的重要形式:深度优先搜索是递归。
2021-03-30 22:16:06
77
原创 [刷题之旅no25]P5318 【深基18.例3】查找文献
这么理解这道题:1.用合适的数据结构储存图2.分别用dfs和bfs对图进行遍历一共有10的五次方个结点,所以如果用二维数据储存路径显然不可行剩下的数据结构还有各种各样的表我需要什么呢?我需要给出一个结点,可以找到其能够直接到达的所有结点这样的话,链式前向星可以用来存图(好万能)存图过程中还需要判断结点大小进行插入。然后对当前结点进行遍历,深搜即可。由于论文不可以相互引用,所以所有结点都是单向的深搜:给一个结点,遍历和当前结点直接相连的所有结点,遍历一个,打印一个,递归一个广搜:给一个结
2021-03-30 22:10:50
194
原创 [刷题之旅no24]P1185 绘制二叉树
这道题更像一道数学题只要给出确定层数那么层与层之间的高度差可以被直接计算出来也就是每一层所在二维字符数组中的纵坐标可以被计算出来当二叉树确定之后,如果给定确定的第几层第几个结点,也可以把这个结点的坐标计算出来如果给定层级,也可以把这个层级的结点所影响到的范围也计算出来这样我们便可以根据给定的层级建造出相应的二叉树通过给定结点计算出节点位置和节点的影响范围然后把整个结点的影响范围删除,结点影响的整个范围不好计算,还是递归删除把递归参数需要点的坐标,如果是向下遍历,则需要见到什么删除什
2021-03-30 20:28:11
257
原创 [刷题之旅no23]P4913 【深基16.例3】二叉树深度
求解二叉树深度…这样太。。刚才我做的题中就有啊好吧,还是有点难度的,毕竟这道题的输入数据很。人性化。也就是说规则有点模糊?我们还是想办法确定一下数据结构好了。特殊点1.只要有儿子,必定有两个2.从左到右给儿子3.如果是0没儿子难点:确定合适数据结构储存输入数据用队列!因为他的子节点是按照顺序给的,从上到下,从左到右,所以先到先得,我们只需要使用一个队列,让非0结点入队即可。而且不断更新grade数组的值好的,当前80分,有一道题出错了,我需要猜想我的逻辑不全面的地方到底是怎样的
2021-03-29 20:43:25
171
原创 [刷题之旅no22]P1827 [USACO3.4]美国血统 American Heritage
其实这道题,就是给出树的中序遍历和前序遍历,让你写出他的后续遍历哈哈话说这道题跟之前的有点像啊。。思路就是递归别忘了左右边界的变化,上次你在这栽了坑递归函数,1.前序左端点找到根节点2.中序序列之中找到根节点,记录其坐标3.根据中序序列坐标和左右端点,计算左右子树长度,找到左坐标范围4.在前序序列中找到找到左右子树的坐标范围5.左子树递归,右子树递归6.打印根节点7.结束递归结束条件。左右端点相等,说明只剩一个点了好吧,看来又出现了我最害怕的逻辑出错了,这些下标算起来真是有点烦人
2021-03-29 19:47:11
122
原创 [刷题之旅no21]P3884 [JLOI2009]二叉树问题
题目输入:二叉树结点数量结点之间相邻情况需要求距离的两个结点编号输出:二叉树的深度,宽度和给定两个编号之间的距离问题所在:1.选定一个比较好的数据结构储存题目给定的数据2.利用这个数据结构把树的深度,宽度和给定两个结点之间的距离求出来。一、求树的深度:从根节点遍历整个树记录当前深度,时刻更新最大值即可二、求树的宽度:设置层级概念,也就是当前节点到根节点的路程长度+1;统计所有层级的节点数,取最大值即可。三、给定两个结点之间的距离:采用由下向上的方法例如给定两个节点a,b.那么
2021-03-29 18:49:53
126
原创 [刷题之旅no20]P1131 [ZJOI2007] 时态同步
这道题,理解一下每两个点之间的路径唯一,所以距离唯一给定一个特定的结点,现在求解:怎么样加路径长度,使得当前结点到其他结点的路径相等(要求求最小值)。。相当没有思路奥我现在的思路:相当空旷!1.用什么数据结构(或者说怎么构建这个树)如何建造这棵树呢?问题:题目给出的是两个结点,和链接两个结点之间的通路所以无法判断子父节点如何判断子父节点?激发点是1级结点和1级结点相连的是2级结点和2级结点相连的是3级结点和同一个结点相连的是同一级结点所以我就一遍遍遍历用一个三维数组记录题目数
2021-03-28 22:03:58
92
原创 [数据结构no1]链式前向星
链式前向星,就是邻接表的改良版由一个结构体数组,一个int下标,一个head数组组成typedef struct { int to,next,dis;}Edge;Edge edge[length];int cnt=0;head[length];//利用函数构造一条边void creategde(int from;int to;int dis){ cnt++; edge[cnt].next=head[from]; edge[cnt].to=to; edge[cnt].dis=di
2021-03-28 21:42:44
123
原创 [刷题之旅no19]P1087 [NOIP2004 普及组] FBI 树
思路,递归分治函数:参数就是结点在字符串上面的区间,L,R首先设置cnt0和cnt1=0;递归终止条件就是L==R此时判断是0还是1,打印B或者I//出错然后递归左子树,区间就是[L,R/2];递归右子树,区间就是[R/2+1,R];//出错然后看当前是F还是I,直接遍历即可for(int i=L;i<=R;i++){if(==1;if(==0if(cnt0*cnt1!=0printf}if(cnt0else if(cnt1return出现了一个错误,导致递
2021-03-28 11:51:44
230
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人