数据结构算法
文章平均质量分 71
闪电侠的博客
追求优雅,简洁的代码
展开
-
非递归先序中序后序遍历二叉树
先序遍历void preOrder(TNode* root){ if ( root != NULL) { Stack S; S.push(root); while (!S.empty()) { TNode* node = S.pop(); Visit(node原创 2013-03-28 10:47:05 · 1393 阅读 · 1 评论 -
DP系列之二进制状态压缩--杭电1074
状态压缩的意图是用每一位二进制表示一个状态,0表示选中状态,1表示不选状态,如果有N个物体,从中选择若干个物体,那么最终选中的状态可以用一个N位的二进制位来表示比如若选择了第1个物体和第3个物体,这种状态为0...0101 //前面的0的个数为N-3若选择了第2个物体,第3个物体,第N个物体,这种状态为1...0110因此,无论选中什么状态,都可以用一个N位的二进制数来表示原创 2013-01-28 21:17:09 · 2193 阅读 · 1 评论 -
菜鸟都能理解的0-1背包问题的空间优化
如果你不知道什么叫做0-1背包问题,下面是0-1背包问题的简单描述假设有n件物品每件物品的体积为w1, w2……wn 相对应的价值为 v1, v2.……vn。01背包是在n件物品取出若干件放在空间为total_weight的背包里,使得背包的总体积最大关于0-1背包问题没有优化版本,请看这里上面的核心代码是下面这一段 for (int i = 1; i <原创 2013-01-18 14:55:06 · 4476 阅读 · 0 评论 -
杭电oj 2544 固定起点终点最短路径解题报告
注:鄙人最近按照此分类来刷题,假期的最低限度是刷掉所有的DP类,并且每一道题目写一个解题报告,如果有志同道合的朋友,欢迎加QQ 823797837共同学习交流,也可以加群ACM新手群161986576,老鸟飞过Problem Description在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上原创 2013-02-08 21:32:44 · 2466 阅读 · 0 评论 -
杭电2059解题报告
Problem Description据说在很久很久以前,可怜的兔子经历了人生中最大的打击——赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成了绝技,能够毫不休息得以恒定的速度(VR m/s)一直跑。兔子一直想找机会好好得教训一下乌龟,以雪前耻。最近正值HDU举办50周年校庆,社会各大名流齐聚下沙,兔子也趁此机会向乌龟发起挑战。虽然乌龟深知原创 2013-02-07 18:44:03 · 1092 阅读 · 0 评论 -
华为迷宫算法c++完整实现
原题是迷宫游戏,迷宫只有一个入口和出口,请编写程序输出一条从迷宫入口到出口的路径。为了简单起见,用一个二维数组表示迷宫,0表示可以行走,可以向东,东南,南,西南,西,西北,北,东北八个方向行走, 但不能行走出界,必须从出口出去, 1表示墙不能行走。输入要求:输入文件input.txt第一行包含两个整数row,column, row表示迷宫的行,column表示迷宫的列, 接着row行,原创 2013-01-01 16:39:17 · 1720 阅读 · 0 评论 -
LRJ生成可重复的排列
#include using namespace std;void print_emu(int a[], int x[], int n, int cur) { if (cur == 3) { for (int i = 0; i < 3; i++) cout << x[i] << " "; cout << endl; return; } else原创 2013-01-20 20:14:52 · 800 阅读 · 0 评论 -
回溯算法:子集树和排列树
假设现在有一列数a[0],a[1], ...a[n-1]①如果一个问题的解的长度不是固定的,并且解和元素顺序无关,即可以从中选择0个或多个,那么解空间的个数将是指数级别的,为2^n,可以用下面的子集树来表示所有的解(假设这里n=4)PIC. 子集树子集树的算法框架为void backtrack(int t) {//表示访问到第t层,t从0开始if (t原创 2013-01-18 22:11:41 · 8559 阅读 · 1 评论 -
回溯法例题之子集树:数组定和问题
问题描述:给定一个数组a和一个整数sum,在数组中取若干个数使得他们的和等于sum问题分析:数组中的元素要么选择,要么不选,且无序,每一种选择都可以看做是解空间的一个元素X[i] = 0或1(0如果我们假设当前已经处理了前t个元素(这t个元素或者选,或者不选),他们的和为c,那么在处理第t+1个元素时,要满足c + a[t+1] #include using namespace原创 2013-01-20 15:20:49 · 1939 阅读 · 0 评论 -
杭电acm1028利用母函数求解数字拆分问题
http://acm.hdu.edu.cn/showproblem.php?pid=1028选择母函数 (1+x+x^2+x^3+x^4+x^5+…x^n)*(1+x^2+x^4+x^6+…)*(1+x^3+x^6+x^9+…)*…*(1+x^n)最后的组合方案为x^n的系数,为什么呢?第一个因子(1+x+x^2+x^3+x^4+x^5+…)中x的幂表示组合中可以取的1的个原创 2013-01-05 21:40:26 · 1010 阅读 · 0 评论 -
c++实现将简单的中缀表达式转化为…
不多说了,都在代码里了,假设只有加法和乘法,除法和减法类似#include #include using namespace std;bool isNotOperator(char c) { return c != '*' && c != '+'&& c!= '(' && c != ')';}//获取符号的优先级int getPriority(char c) { in原创 2012-12-27 11:27:07 · 680 阅读 · 0 评论 -
回溯经典之素数环问题
问题描述:假定有从1...n这n(n思路1.我们可以假定已经有一个序列满足任意两个数之和是素数2.下一步要做的就是扩充这个序列,即从剩下的数中寻找一个数,使得这个数和既定序列中最后一个数的和是素数3.如果这个数是最后一个数,那么判断它和第一个数相加的结果是否为素数,如果是,就打印序列,否则什么也不做因为要求的是环,我们可以假定从任意一个数开始,这里假设从1开始/原创 2013-01-21 19:10:32 · 1038 阅读 · 0 评论 -
菜鸟都能理解的看毛片(KMP)算法
下面我们来见识一下神奇的看毛片算法看毛片算法的思想是用两个指针i和j来指示A和B中的一个位置1) 用i来表示当前匹配到A中的哪个位置啦2) 用j来表示当前匹配到B中的哪个位置啦3) 并且要满足B[1...j]要和A[i+j-1...i]相等哦?很难理解啊,下面的图(图1)应该使你能够一拍脑袋,“哦,我太聪明了,这么简单!”原创 2013-01-17 20:43:33 · 89772 阅读 · 5 评论 -
归并排序求逆序对
逆序对的定义:在一个数组a中如果有两个元素满足i a[j],那么(i, j)就称为数组中的一个逆序对现在,我们要求的是,给定一个长度为N的数组a,求出该数组的逆序对的个数比如 int a[4] = {7, 5, 6, 4} 逆序对为(7, 6), (7, 5), (7, 4), (6, 4), (5, 4)1.常规的做法是依次枚举所有的元素对(a[i], a[j]),显然,这原创 2013-04-12 21:00:15 · 2932 阅读 · 0 评论 -
c++中关于explicit的一些总结
首先看下以下代码#include using namespace std;class A{ public: A(int v): value(v) { cout << "构造" << endl;} int value;};void f(A a){ cout << "f()" << endl;}int main(){ f(1); return原创 2013-04-17 21:19:55 · 1145 阅读 · 0 评论 -
菜鸟都能理解的线段树入门经典
线段树的定义首先,线段树既是线段也是树,并且是一棵二叉树,每个结点是一条线段,每条线段的左右儿子线段分别是该线段的左半和右半区间,递归定义之后就是一棵线段树,图示如下图1.线段树示意图定义线段树的数据结构struct Line{ int left, right, count; Line *leftChild, *rightChild;原创 2013-03-22 14:00:17 · 4941 阅读 · 4 评论 -
如何判断一个单链表有环,并且求出交汇处
单链表有环的情景如下,为了方便起见,假定入口之前的链表长度为L,循环长度为K循环链表示意图我们可以用两个指针,p1每次移动一格,p2每次移动两格,初始化都为头结点HEAD随着指针慢慢推进,一定会出现以下的情况某一时刻两指针的情况第一步现在,我们可以假定再经过t次移动之后,两者会在某一处相遇,对照上图对于P1,t次移动后的位置为t原创 2013-03-19 22:02:55 · 1508 阅读 · 2 评论 -
杭电ACM题目分类
注:最近在刷字符串类别的题目,计划在3月15号之前刷完,欢迎加QQ 823797837共同学习交流,也可以加群ACM新手群161986576,老鸟飞过基础题:1000、1001、1004、1005、1008、1012、1013、1014、1017、1019、1021、1028、1029、1032、1037、1040、1048、1056、1058、1061、1070、1076、1转载 2013-01-05 04:15:49 · 1922 阅读 · 0 评论 -
把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,不能申请额外的空间
例如AbcDeFGhi ->bceiADFG这道题目是今年腾讯的面试题,我的想法是基于冒泡的思想,从头开始扫描,遇到小写字母就往前面冒初始:AbcDeFGhi冒'b': bAcDeFGhi冒'c': bcADeFGhi冒'e': bceADFGhi冒'h': bcehADFGi冒'i': bcehiADFG得到最终结果为bceiADFG最终代码如下#i原创 2013-03-15 14:19:17 · 1747 阅读 · 2 评论 -
字典树实现map容器
通过hdoj1075来演示如何通过字典树创建map容器字典树的结构如下其中,根结点上不存储数据,每个结点有唯一的字符串(key)标示,可在对应的结点中存储相应的值(value),比如ah结点上可以存储数据"I am handsome!"那么,对应的map中一条为["ah" -> "I am handsome!"],字典树的数据结构中最多有MAX个子树,假如由26个英文字原创 2013-02-17 20:26:35 · 1159 阅读 · 0 评论 -
回溯法经典—n-皇后问题
n-皇后问题是回溯法中经典中的经典,其基本问题描述是:在一个nxn的格子中放n个皇后,使得每个皇后不能相互攻击,任意两个皇后能够互相攻击的条件是他们在同一条对角线或者同一行或者同一列上问题可以转换为从第0行开始放置皇后一直放到n-1行,使得每一行在放置皇后的同时,不能与前面的皇后相互攻击即列,对角线不冲突即可(行肯定不冲突)伪代码描述search(cur) { //表示开始放置原创 2013-01-20 22:14:30 · 1264 阅读 · 0 评论 -
杭电1176解题报告
原题见这里关于解题的详细步骤都已经在代码注释里面了,这里一定要注意,刚开始gameboy在位置5,因此在第5秒钟之前,他的活动范围有限,所以,在循环的时候j的范围不一定能从0到10#include using namespace std;int a[100001][11];int dp[2][11];int main() { //dp[i][j]表示第i秒钟在位置j原创 2013-02-02 22:35:45 · 966 阅读 · 0 评论 -
c/c++实现利用二叉树的先序遍历和中序遍历序列重建树
先序遍历中第一个结点必然是根结点,利用该结点在中序遍历中的位置,将树分为左子树和右子树,然后递归重建左子树和右子树,代码如下#include using namespace std;struct Node { char value; Node* left; Node* right; Node() { }; Node(char c, Node* l = NULL, Node原创 2013-01-01 14:04:25 · 2719 阅读 · 0 评论 -
判断出栈顺序是否正确,c++实现
现有N个元素1,2...N顺序入栈,给出一个出栈序列a1, a2...an判断此出栈序列是否正确,游戏规则是:元素必须后进先出首先,我们将出栈顺序保存在一个数组target[N]中,用一个变量current来模拟入栈(当然,要建立一个栈空间stacks),num来表示出栈顺序的当前编号,current和num都初始化为1那么,下面应该这样来处理1. 如果当前出栈元素target原创 2012-12-31 10:35:13 · 4040 阅读 · 0 评论 -
c++实现0-1背包问题完整源码(动态…
[cpp] viewplaincopy#include #define MAX_NUM 5 #define MAX_WEIGHT 10 using namespace std; //动态规划求解 int zero_one_pack(int total_weight, int w[], int v[], int fla原创 2012-12-27 11:27:25 · 1528 阅读 · 0 评论 -
c++实现图的邻接表(带有权值和入度…
#include using namespace std;struct Node { //定义表结点 int adjvex; //该边所指向的顶点的位置 int weight;// 边的权值 Node *next; //下一条边的指针};struct HeadNode{ // 定义头结点 int nodeName; //顶点信息 int inDegree原创 2012-12-27 11:27:14 · 3474 阅读 · 0 评论 -
c++实现树的广度搜索和深度搜索完…
#include #include using namespace std;struct Node { //定义表结点 int adjvex; //该边所指向的顶点的位置 Node *next; //下一条边的指针};struct HeadNode{ // 定义头结点 int nodeName; //顶点信息 bool visited;//表示该结点是否原创 2012-12-27 11:27:18 · 715 阅读 · 0 评论 -
Union-Find 按大小求并算法
#include#includeusing namespace std;class UF{ public: UF(int size): vec(size),parent(size) { for(int i = 0; i vec[i] = i; parent[i] = -1; } } void Uni原创 2012-12-27 11:27:11 · 995 阅读 · 0 评论 -
最优二叉查找树的详细分析,c++代码实现
首先看下关于最优二叉查找树的描述给定一个由n个互异的关键字组成的序列K={k1,k2,...,kn},且关键字有序,对于每一个关键字ki,一次搜索为ki的概率是pi。某些搜索的值可能不在K内,因此还有n+1个虚拟键d0,d1,...,dn代表不再K内的值。d0代表所有小于k1的值,dn代表所有大于kn的值,对于i=1,2,...,n-1,di代表所有位于ki和ki+1之间的值。对每个虚拟键di原创 2012-12-26 19:26:10 · 2767 阅读 · 0 评论 -
c++实现树的广度搜索和深度搜索完整代码
#include #include using namespace std;struct Node { //定义表结点 int adjvex; //该边所指向的顶点的位置 Node *next; //下一条边的指针};struct HeadNode{ // 定义头结点 int nodeName; // 顶点信息 bool visited; //表示该结点是否原创 2012-12-24 19:26:45 · 1743 阅读 · 0 评论 -
杭电1006,神题啊!
#include using namespace std;struct Set { //表示集合[a, b] double a; double b; Set() {} Set(double _a, double _b): a(_a), b(_b) {}};Set intersection(Set s1, Set s2) { Set s; s.a = s1.a >原创 2013-01-02 21:04:13 · 1095 阅读 · 0 评论 -
c++实现分治法最近点对算法
最近点对的算法是分治法的典型代表,所求的是平面上一堆点,求所有点对的距离的最小值,如果用暴力方法,其复杂度高达O(n*n)显然,效果太差,分治法的思想是将平面上的点分成左右两半,分别求左右两半的最小距离,然后取一个最小值,当然,最近点对还可能会有这样的情况,即一个点在左半边,一个点在右半边,这里,并不需要用暴力的方法求解所有的左边的和右边的最近点对,而是通过数学的一些证明将分治的其余代价降到O(n原创 2013-01-05 10:45:55 · 6873 阅读 · 1 评论 -
c++实现0-1背包问题完整源码续(动态规划+回溯法实现)
//回溯法是将解空间映射为一棵解空间数(二叉树),第i层的结点代表第i个待选结点,以i为根,往左延生就代表选择该结点,往右延生表示不选该结点//每个叶子结点有唯一一条路径代表一个解#include #define MAX_NUM 5#define MAX_WEIGHT 10using namespace std;//动态规划求解int zero_one_pack(int total_原创 2012-12-27 16:11:32 · 2117 阅读 · 0 评论 -
杭电1203回溯+DP
回溯方法是正确的,但是LTE#include using namespace std;inline void offer(int w[], float v[], int n, int& sum, int i,float &mmin, int total, float& c) { if (i == n) { if (c < mmin) mmin = c; ret原创 2013-01-18 10:51:09 · 1289 阅读 · 0 评论 -
杭电1160解题报告
原题见这里题目的大概意思:有一系列老鼠,每个老鼠有体重w以及奔跑的速度s,求这样一个最大的序列,使得m[i+1].w > m[i].w && m[i+1].s 一开始,我用“DAG上的动态规划”来解决这道题目,把每一个老鼠看成是有向图中的一个顶点,有向边(v1, v2)存在的充要条件是m[v2].w > m[v1].w && m[v2].s 那题目就转换为求一个DAG中不确定起点的原创 2013-02-02 13:39:09 · 1039 阅读 · 0 评论 -
c++实现0-1背包问题完整源码(动态规划实现)
#include #define MAX_NUM 5#define MAX_WEIGHT 10using namespace std;//动态规划求解int zero_one_pack(int total_weight, int w[], int v[], int flag[], int n) { int c[MAX_NUM+1][MAX_WEIGHT+1] = {0}; //c[原创 2012-12-27 11:21:14 · 4440 阅读 · 4 评论 -
c++实现哈夫曼编码完整代码
#include #include #include #include #include using namespace std;class Node { public: char c; //表示字符 int frequency; //表示该字符出现的次数或频率 Node *left; Node *right; Node(char _c原创 2012-12-25 13:53:13 · 7742 阅读 · 2 评论 -
杭电OJ——1024 Max Sum Plus Plus 详细分析+优化全过程
Problem DescriptionNow I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more di原创 2013-01-27 22:58:23 · 3416 阅读 · 0 评论 -
中国剩余定理(也叫孙子定理)
今儿偶尔无聊,看到一个叫做“中国剩余定理”的玩意,觉得煞是好玩,便写一点总结上题目先,假设一个数(1)被3除余2,(2)被5除余4,(3)被7除余6,求满足条件的最小整数lcm(5, 7) 为35 35*2=70刚好除以3余数为1lcm(3, 7) 为21 21*1=21刚好除以5余1lcm(5, 3) 为15 15*1 = 15刚好除以7余1接下来(70*2 +21*原创 2013-01-10 12:42:33 · 1336 阅读 · 1 评论 -
c++实现欧拉回路问题
欧拉回路问题由七桥问题而来,其基本问题是是否能一次性不重复地走遍这七座桥,转换为数学问题中的图论就是指的是从图中的一个顶点出发,是否能够一次性不回头地走遍所有的边,算法代码如下#include #include using namespace std;int G[5][5];int visited[5][5];int n = 5;void euler(int u) { for原创 2013-01-07 14:28:37 · 5525 阅读 · 0 评论