数据结构和算法
UKey_
勿以浮沙筑高台
展开
-
数据结构与算法学习-并查集
并查集(Union-Find Set): 用于解决若干的不相交集合的如下几种操作的统称: 1.MAKE-SET(x):初始化操作,建立一个只包含元素x的集合。 2.UNION(x,y):合并操作,将包含x和y的集合合并为一个新的集合。 3.FIND-SET(x):查询操作,计算x所在的集合。 通常使用树这种数据结构来表示集合,树中的每一个结点代表一个元素,每棵树代表一个集合。那么如何判断两原创 2016-10-08 23:27:03 · 615 阅读 · 0 评论 -
并查集-hdu1232
并查集的水题,模板一套,基本什么都不用改。 代码如下: #include <stdio.h>#define MAXN 1010int root[MAXN], ans;int Find(int x){ while(x != root[x]) { x = root[x]; } return x;} void Union(int x, int原创 2016-11-02 00:32:38 · 367 阅读 · 0 评论 -
深度搜索poj1979
题目的意思是可以到达多少个点,’.’代表可以走的,’@’代表当前位置,’#’代表障碍物。每次只能走上下左右这四个方向的其中一个。 思路:一道简单的深搜题,开个二维数组从当前位置开始搜四个不同的方向就行了。 代码如下: #include <iostream>using namespace std;#include <cstdio> char map[25][25]; //记录迷宫in原创 2016-11-19 16:10:19 · 476 阅读 · 0 评论 -
深度搜索hdu1010
题目的大概意思是一只狗能不能在规定时间到达出口。如果可以,就输出”YES”,否则输出”NO” 思路:一道深度搜索的题,如果直接暴力搜索会超时,所以需要剪枝。当起点和终点的最短距离(无视障碍物)比规定的时间大的时候肯定是满足不了的,这是其中一个剪枝。还有一个很关键的剪枝,我们判断图的每个点是奇数还是偶数,如果起点和终点都是奇数或者偶数,那么需要的时间(步数)应该是偶数步,否则是奇数步。 比如:原创 2016-11-19 19:10:12 · 556 阅读 · 0 评论 -
广度搜索hdu1548
题意:有个电梯在每一层只有固定的往上的楼数和往下的楼数,求起点到终点的电梯最少移动的步数 思路:广度搜索按层搜索即可,每次记录步数,一到终点就退出循环。用C++的STL队列要方便些。 代码: #include <iostream>using namespace std;#include <queue>#include <stdio.h>#include <string.h>int N,原创 2016-11-19 20:11:44 · 486 阅读 · 0 评论 -
KMPhdu2594
题意大概就是输入串s1和s2,问s1的前缀和s1的后缀的公告部分最长是哪个子串 思路:可以把两个串连成一个串,然后利用Kmp算法的next数组求出最长的相匹配的前缀和后缀就行了。 #include<stdio.h>#include<string.h>char a[50010];char b[100010];int next[100010];int m,n;void GetNext原创 2016-11-19 21:37:24 · 654 阅读 · 0 评论 -
KMPhdu2203
题意就是两个串s1,s2,如果s2是s1的子串就输出yes,不然输出no,而且s1从尾部到头部循环过来也算。就比如样例中的AABCD 和 CDAA,这样也算匹配成功。 思路:用KMP算法查找子串就可以了,事先把s1自我复制一遍,就比如AABCD,把它复制成AABCDAABCD,再当作主串去比较就可以了。貌似c++有个函数strstr()可以直接匹配子串欸。 #include<stdio.h>原创 2016-11-19 21:56:35 · 485 阅读 · 0 评论 -
广度搜索hdu1372
题意大概就是在国际象棋上,问马从a点到b点需要的最短步数。马的走法和中国象棋的类似。 思路:这种求最少步数或者最小次数的题一般都是用广度搜索来解就行了。#include <iostream>using namespace std;#include <queue>#include <string.h>int s1, s2, e1, e2;int map[8][8];int x2x[8]原创 2016-11-19 23:06:31 · 530 阅读 · 0 评论 -
扩展欧几里得算法poj1061
题意大概是两只青蛙在长度为L的坐标上的x点和y点分别每步跳n和m个点,问能不能相遇,如果能相遇,输出最少步数. 思路:用扩展欧几里得算法求不定方程ax+by=c。扩展欧几里得的数学证明好多。。。。 #include <iostream>using namespace std;#define LL long longLL Gcd(LL a, LL b){ return b ? Gcd原创 2016-11-20 13:04:29 · 519 阅读 · 0 评论 -
拓扑排序hdu1285
题意 有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。 思路:由题意可知这些输赢的关系不可能构成一个圈,比如1,2,3三队,1赢了2,2赢了3,3赢了1,这样的话,输原创 2016-11-20 13:54:12 · 619 阅读 · 0 评论 -
Dijkstra算法51NOD1459
题意:你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的原创 2016-11-20 15:27:26 · 827 阅读 · 0 评论 -
树状数组hdu1541
题意:大概就是计算每颗星星左下边包括了多少颗星星,这个数值就是level。左下边不包括本身,不超过本身的x,y的坐标,可以等于。问每种level有多少颗星星。 思路: 1. 每次输入一个坐标对之后,都要计算一下这个它的level。 2. 此题的x坐标可以为0,而树状数组是从1开始的,所以处理的时候对每个x坐标进行加一即可。输出从level=0,开始。 代码如下: #include <i原创 2016-11-20 16:40:53 · 483 阅读 · 0 评论 -
二叉搜索树hdu3791
题意:判断两序列是否为同一二叉搜索树序列 思路:创建了二叉搜索树之后,随便用一个遍历方法来判断两棵二叉树的每个结点的值是不是相等的就可以了。 代码: #include <iostream>using namespace std;#include <string.h>#include <stdlib.h>#include <stdio.h>#include <malloc.h>typ原创 2016-11-22 10:44:15 · 497 阅读 · 0 评论 -
线索二叉树
线索二叉树是为了便于访问一个结点的前驱和后继的信息。它在每个结点上新增了两个标志位,用来判断当前结点到底有没有左子树/右子树,如果没有,就把其利用起来存前驱/后继的信息。同时它也新增了一个头节点用来将整个二叉树联系起来。具体实现如下,有大量注释便于理解。#include <iostream>using namespace std;#include <cstdio>#include <cstri原创 2016-11-22 20:14:31 · 450 阅读 · 0 评论 -
字典树hdu1251
字典树: 用于统计、排序和保存大量的字符串,它的优点是节约了存储空间,并且查找的效率很高。 题意: Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). 思路:用字典树存储单词表,在建树的过程中就记录该单词出现的次数,然后查询的时候,直接输出对应的单词的次数就行了。比如样例中单原创 2016-11-23 20:32:00 · 379 阅读 · 0 评论 -
字典树hdu1247
题意:如果有个单词是由其它两个单词组成的,就输出。 思路:每个结点加个标志位,判断是不是一个完整的单词。如果进行查找操作,查找成功之后,把查找成功的部分截掉,查找剩下的部分,如果也查找成功,那就输出。比如“a ahat hat”,”ahat”在字典树中查找时,找到’a’是一个单词,截掉’a’的部分,剩下”hat”,继续找,找到了”hat”,就证明是由两个单词组成的了。#include <iostr原创 2016-11-23 21:24:28 · 419 阅读 · 0 评论 -
最小生成树(Prim)poj1258
题意:给定N个村庄和两两村庄的距离,求将这N个村庄联通所需的最小电线长度。 思路:就是一道最小生成树的题,用prim或者kruskal都可以实现,我用的prim。 代码: #include <iostream>using namespace std;#include <cstring>#define MAXV 101#define INF 0x3f3f3f3fint map[MAXV原创 2016-12-13 16:16:01 · 688 阅读 · 0 评论 -
二叉树非递归遍历
二叉树的各种遍历方法中,非递归的遍历要比递归遍历更加复杂一些,但是听说在面试中也更容易考到。如果有什么不理解的地方,自己画下图然后结合上代码很容易理解的。#include <iostream>using namespace std;#include <cstdio>#include <cstring> #include <malloc.h> #include <queue>#includ原创 2016-11-29 14:02:22 · 865 阅读 · 0 评论 -
并查集-hdu1272
这道题也是一道相对简单的并查集的题目,要满足小希的要求只需要满足这样两个条件: 1. 图是连通的,即点数=边数+1 2. 图中无环 上代码: #include <stdio.h>#define MAXN 100010int root[MAXN];int Find(int x){ while(root[x] != x) { x = root[x];原创 2016-11-01 00:00:00 · 342 阅读 · 0 评论 -
并查集-hdu1213
一道很简单的并查集入门题,唯一坑的是用路径压缩居然超时了。。。。没做优化也能过#include <stdio.h>int root[1010];int Find(int x){ while(root[x] != x) //找到根节点 { x = root[x]; } return x;}int Union(int x, int y){原创 2016-10-31 09:29:15 · 485 阅读 · 0 评论 -
数据结构与算法学习-快速幂取模
当我们遇到类似于求a*b%c这样的问题的时候,如果是a^b%c,当a^b这个数特别大的时候,以至于int范围存不下该值,那最后取模得到的值当然也是错的,这个时候就运用到快速幂取模算法,这种算法的时间复杂度是O(logn),效率非常快,也是常用的几种算法之一。 快速幂取模依赖于以下数学公式: 以及a*b%c = ((a%c)*(b%c))%c 用二分的思想把b分为奇数和偶数,再运用公式按步求原创 2016-10-09 11:17:11 · 1170 阅读 · 0 评论 -
二叉树-求{0,1....n-1}的非空子集
今天有同学问了下我怎么编程实现求集合{0,1….n-1}的非空子集合,我发现这恰好是一棵满二叉树的题,可以用二叉树求解。 代码如下: #include <iostream>using namespace std;#include <stdlib.h>int n ;int flag[20]; typedef struct binary_tree{ int data;原创 2016-10-09 18:13:32 · 743 阅读 · 0 评论 -
poj算法刷题进阶
OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期:一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法.转载 2016-09-20 21:09:13 · 1633 阅读 · 0 评论 -
栈和队列
一. 栈是一种特殊的线性表,特点是:后进先出(LIFO),先进栈的元素后出栈,后进栈的元素先出。基本操作:栈的初始化、判断栈空、入栈、出栈等。比如,堆放一堆书,取出来的当然是第一本了,一本书放到这个书堆也是放在最上面,当然,你要是抽出来。。。。那我也没办法 栈的存储方式有两种,一个是用数组存储,另外一种是使用链表存储。使用数组存储需要注意判断栈的上溢或者下溢。上溢:超过了数组的大小。下溢:数组中原创 2016-09-24 21:47:04 · 565 阅读 · 0 评论 -
数据结构与算法学习--邻接表
众所周知,图的存储方式有两种,一种是领接矩阵(即二维数组),还有一种是领接表。 领接矩阵适合于稠密图,领接表适用于稀疏图(点多边少)。 领接表即给图中每个顶点创建一个单链表,第i个单链表中的结点表示依附于顶点Vi的边,每个单链表的头节点形成一个一维数组,以便于顶点的访问。具体代码如下: #include <iostream>using namespace std;#include <mal原创 2016-10-21 11:36:08 · 724 阅读 · 0 评论 -
动态规划-硬币问题
动态规划的本质是将原问题分解为同性质的若干个相同子结构,以局部最优值求得最优值。它和普通递归求解好处在于可以避免大量的重复计算。求解动规需要找到问题本质的状态,利用已知状态,推出状态转移方程。有了状态转移方程,什么都好说了。 以3个硬币的价值分别为1,3,5,然后要得到值为value的最少硬币数ans为例,下面表示的意思是d(value) = ans: d(0) = 0//方案只有1种 d(1原创 2016-11-02 23:07:41 · 869 阅读 · 0 评论 -
辗转相除法求最大公约数-hdu1019
题目的意思就是要求输入n个数,然后通过这n个数求解最小公倍数。每个数据范围小于int。 (x和y的最小公倍数) = (x*y)/(x和y的最大公约数) 问题就转换成求最大公约数,求最大公约数有个算法是欧几里得辗转相除法。 辗转相除法求最大公约数: 步骤1. 将x除以y,记余数为r 步骤2. 如果r等于0,那么y就是x的最大公约数 步骤3. 如果r不等于0,那么将y看成新的x,将r看成新原创 2016-11-03 18:50:30 · 508 阅读 · 0 评论 -
动态规划-hdu1203
Problem Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到原创 2016-11-03 20:53:49 · 537 阅读 · 0 评论 -
匈牙利算法入门
最近了解了一下二分图匹配,发现这篇博客写的挺好,自己总结的话也总结不了那么好,于是就转载过来了,出处http://www.cnblogs.com/budapeng/articles/3273293.aspx首先来了解下一些概念性的东西。二分图: 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),转载 2016-11-05 21:41:57 · 1812 阅读 · 1 评论 -
排序算法-直接插入排序
直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。 大致思路就是:把数组中的元素一个一个遍历一遍,寻找该元素应该插入的位置,使得数组有序。待遍历的元素都会用key值记录下来,方便插入操作。其实就是不断地比较、记录key、移位和插入的过程。这里使用算法导论上的图片 ,数组A[6原创 2016-09-30 17:42:51 · 631 阅读 · 0 评论 -
排序算法-快速排序
快速排序:快排是对冒泡排序的一种改进,它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 快排的执行思路是遵照分治模式的。有如下三个步骤: (1).分解:将数组依据某个值划分成两个部分; (2).解决:通过递归调用,将每个部分分别进行排序; (3).合并:因为排序就在内部完成,所以不需要原创 2016-09-30 17:19:53 · 698 阅读 · 0 评论 -
数据结构与算法学习-哈希表入门
哈希表:又叫散列表,关键值通过哈希函数生成一个哈希地址映射到数组对应的存储位置上,查找时通过关键值直接访问数组。就好比把一个复杂的事务通过一种方式简化成一个小物件,这个小物件就代表了这个复杂的事物。哈希函数:指的是关键值和存储位置建立的对应关系。一般我们只需要一次查找就能找到目标位置,但有些关键字需要多次比较和查找才能找到。因为哈希表里,可能存在关键值不同但是由于哈希函数的计算方式导致生成原创 2016-10-04 20:55:57 · 731 阅读 · 0 评论 -
数据结构与算法学习-二叉树
二叉树是一种特殊的树型结构,它的每一个结点最多只有两个子结点。二叉树根据子结点的不同可以分为:1.完全二叉树:如果一棵树的高度为h,那么除了第h层外,其它各层的结点数都达到最大值,第h层有叶子结点,并且叶子结点都是从左到右依次排布。2.满二叉树:除了叶节点外每一个节点都有左右子叶且叶子结点都处在最底层的二叉树。3.平衡二叉树:又称AVL树,它是一棵二叉排序树,具有这样的性质:它是一原创 2016-10-04 21:23:27 · 560 阅读 · 0 评论 -
数据结构与算法学习-堆排序
堆排序: 堆的标准定义如下: n个元素的序列{k1, k2, …, kn}当且仅当满足以下关系时,称为堆。 (Ki<=K2i&&Ki<=K2i+1)或(Ki>=K2i&&Ki>=K2i+1) (i = 1, 2, ..., n/2) 可以简单理解为就是一个完全二叉树,但是比较特殊,即完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。 示例: 小顶堆:意思就是堆原创 2016-11-10 18:56:57 · 487 阅读 · 0 评论 -
hdu1040-堆排序
就是一道简单的排序题,刚学了堆排序,就用堆排序做了。 #include <iostream>using namespace std;#include <stdio.h>#define MAXN 1001int min(int x, int y){ if(x < y) return 1; return 0;}void HeapAdjust(int a[]原创 2016-11-10 19:27:39 · 518 阅读 · 0 评论 -
哈夫曼树的基本构建与操作
看到的讲解huffman树的一篇比较好懂的博客,唯一不足的地方就是代码里面使用Malloc时没有强制类型转换。。。。出处:http://blog.csdn.net/wtfmonking/article/details/17150499#1、基本概念a、路径和路径长度若在一棵树中存在着一个结点序列 k1,k2,……,kj, 使得 ki是ki+1 的双亲(1从 k1转载 2016-11-29 20:02:32 · 54493 阅读 · 8 评论