挑战程序设计竞赛2 算法和数据结构
文章平均质量分 50
本篇主要是讲《挑战程序设计竞赛2 算法和数据结构》书的读后感和部分题目的再次解读、编程。包括书中的部分代码和一些个人的见解。如果想深入了解,建议去网上买一本回来看,比较适合学习算法的初学者。
小酷miki
这个作者很懒,什么都没留下…
展开
-
第十九章 ALDS1_13_C:15 Puzzle 十六格拼图
知识点 迭代加深:在循环执行深度受限搜索的过程中逐步增加限制值limit,直到找到解为止。 如果当前状态到最终状态的最小成本h加上当前状态深度超过了限制深度d,就可以直接中断搜索。问题链接ALDS1_13_C:15 Puzzle问题内容 求当前16宫格如何移动成目标的16宫格。思路 用A*或者IDA* 算法实现代码IDA*算法#include<iostream> #in原创 2018-01-05 00:21:23 · 704 阅读 · 0 评论 -
第十九章 ALDS1_13_B:8 Puzzle 九宫格拼图
问题链接ALDS1_13_B:8 Puzzle问题内容 求当前9宫格如何移动成目标的9宫格。思路 同样使用回溯的方法去做。代码#include<iostream> #include<cstdio> #include<algorithm>#include<queue>#include<map>#include<string>using namespace std;con原创 2018-01-04 22:20:05 · 489 阅读 · 0 评论 -
第十九章 ALDS1_13_A:8 Queens Problem 八皇后问题
知识点 八皇后问题比较多解法,这里说的是最简单的回溯解法。问题链接ALDS1_13_A:8 Queens Problem问题内容 在8*8的国际象棋棋盘里,有k个皇后已经放好了,皇后会将她的这行、这列、左右斜边上的其他棋子攻击,问如何将8个皇后放到8*8的棋盘保证她们互相不攻击。思路 我们用递归的方式去尝试,在递归完成后若不成功,则恢复原来的状态继续尝试其他的递归。代码#inclu原创 2018-01-04 21:54:12 · 568 阅读 · 0 评论 -
第十八章 数论
问题链接ALDS1_1_C:Prime Numbers 判断n是否是质数#include #include using namespace std;int isPrime(int x) { if (x 2) return 0; else if (x == 2) return 1; if (x % 2 ==原创 2018-01-04 21:28:43 · 323 阅读 · 0 评论 -
第十七章 DPL_3_B: Largest Rectangle 最大长方形
问题链接DPL_3_B: Largest Rectangle问题内容 求最大的干净面积。0代表干净,1代表有污渍。和上一不同的是,这个题目面积可以是长方形的。思路 首先通过以行为直方图,以行为第一遍历,纵向记录每个点当前的最大面积。然后从行向开始动态规划。 利用栈实现。如果栈为空,将当前元素压入栈中。如果栈顶元素的高度(上面一步计算出来的纵向最大面积)小于当前的高度,则压入栈中。如果原创 2018-01-04 21:27:45 · 351 阅读 · 0 评论 -
第十七章 DPL_3_A:Largest Square 最大正方形
问题链接DPL_3_A:Largest Square问题内容 在H*W个边长为1cm的正方形瓷砖,0代表瓷砖有污渍,1代表瓷砖干净。求干净的最大正方形。思路 dp[i][j]代表从瓷砖(i,j)向左上方扩展可形成的最大正方形。 dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1]) + 1代码#include<iostream> #原创 2018-01-01 16:49:17 · 389 阅读 · 0 评论 -
第十七章 DPL_1_D:Longest Increasing Subsequence 最长递增子序列
问题链接DPL_1_D:Longest Increasing Subsequence问题内容 求序列A的子序列中递增序列最长的长度。思路 LCS问题,不懂的点这里最长递增子序列代码#include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using原创 2018-01-01 15:48:09 · 254 阅读 · 0 评论 -
第十七章 DPL_1_B:0-1 Knapsack Problem 0-1背包问题
问题链接DPL_1_B:0-1 Knapsack Problem问题内容 求价值为viv_i、重量为wiw_i的N个物品以及容量为W的背包最多能装的最大价值。思路 基础的01背包问题,不懂的点这里0-1背包代码#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namesp原创 2018-01-01 15:42:14 · 322 阅读 · 0 评论 -
第十七章 DPL_1_A:Coin Changing Problem 硬币问题
问题链接DPL_1_A:Coin Changing Problem问题内容 对于m个面值不同的硬币,求凑成面值为n最少需要多少个硬币。思路 这题不是贪心算法范畴内,这是动态规划相关的问题。 状态转移方程式: T[i][j]=min(T[i−1][j],T[i][j−C[i]]+1)T[i][j] = min(T[i-1][j], T[i][j - C[i]] + 1) T原创 2018-01-01 15:34:24 · 417 阅读 · 0 评论 -
第十六章 CGL_6_A:Segment Intersections: Manhattan Geometry 线段相交问题
知识点 扫描线:将一条与x轴(或y轴)平行的直线向上(向右)平行移动寻找交点的直线。平面扫描算法: 1、将已输入线段的端点按照y升序排序,添加到表EP 2、将二叉搜索树T置为空 3、按顺序取出EP的端点(相当于让扫描线自下而上移动),进行以下处理如果取出的端点是垂直线段的上端点,则从T中删除该线段的x坐标如果取出的端点是垂直线段的下端点,则将该线段的x坐标插入到T如果取出的端点是垂原创 2018-01-01 15:07:03 · 472 阅读 · 0 评论 -
第十六章 计算几何模版
模版#define EPS (1e-10)#define equals(a,b) (fabs((a) - (b)) // 点类class Point {public : double x, y; Point() {}; Point(double x, double y) :x(x), y(y) {} Point operator + (Poin原创 2018-01-01 03:02:38 · 353 阅读 · 0 评论 -
第十五章 GRL_2_A:Minimum Spanning Tree 最小生成树
知识点 我们在第十三章时候讲过最小生成树,我们用的prim算法和邻接矩阵,现在这个题目是顶点数量比较多的情况,所以我们需要使用新的算法。 kruskal算法 1、将图G=(V,E)的边eie_i按照权值升序排列。 2、设最小生成树的边的集合为K,并将其初始化为空。 3、在保证K⋃eiK \bigcup e_i不出现环的前提下,按照i=1,2,…|E|的顺序将eie_i添加原创 2017-12-31 13:53:54 · 335 阅读 · 0 评论 -
第十五章 GRL_5_A:Diameter of a Tree 树的直径
知识点 直径:树的最远结点间的距离问题链接GRL_5_A:Diameter of a Tree问题内容 求出树的直径思路 1、任选一结点s,求到s最远的结点x 2、求到x最远结点y 报告结点x与结点y的距离,即树的直径代码#include <iostream>#include <cstdio>#include <vector>#include <queue>us原创 2017-12-31 13:29:50 · 340 阅读 · 0 评论 -
第十五章 GRL_3_A:Articulation Points 关节点
知识点 关节点:在图G中,如果删除顶点u以及从u出发的所有边后得到的子图不能连通,则顶点u是图G的关节点,也称为割点。问题链接GRL_3_A:Articulation Points问题内容 求出图G的关节点思路利用tarjan算法 代码参考:tarjan算法代码#include<cstdio>#include<vector>#include<algorithm>using nam原创 2017-12-31 13:01:25 · 644 阅读 · 0 评论 -
第十五章 GRL_4_B:Topological Sort 拓扑排序
问题链接GRL_4_B:Topological Sort问题内容 求有向图的拓扑排序思路 利用广度优先搜索或者深度优先搜索都可以遍历。代码广度优先搜索#include <iostream>#include <cstdio>#include <vector>#include <queue>#include <list>#include <algorithm>using name原创 2017-12-31 02:21:59 · 283 阅读 · 0 评论 -
第十五章 GRL_1_C:All Pairs Shortest Path 所有点对间最短路径
知识点 负环:所有边的权值之和为负 弗洛伊德(Warshall-Floyd)算法条件 不包含负环的图执行步骤 设Di,j,kD_{i,j,k}为从ii到jj的只以(1..k)(1..k)集合中的节点为中间節点的最短路径的长度。 若最短路径经过点k,则Di,j,k=Di,k,k−1+Dk,j,k−1D_{i,j,k}=D_{i,k,k-1}+D_{k,j,k-1}; 若最短路径不经原创 2017-12-31 01:34:05 · 1574 阅读 · 3 评论 -
第十四章 DSL_2_C:Range Search (kD Tree) 范围搜索
知识点 范围搜索:从拥有多个属性的报表集合(数据库)中,寻找具有特定属性且位于指定范围内的元素。问题链接DSL_2_C:Range Search (kD Tree)问题内容 求出矩阵区间内的点的个数思路 构建二维的二叉搜索树,利用深度奇偶性区分x,y的维度去搜索,对于当前的范围如果在搜索的范围则加入到数组中,不然就拆开范围往下遍历。代码#include <iostream>#in原创 2017-12-31 00:56:52 · 620 阅读 · 0 评论 -
第十四章 DSL_1_A:Disjoint Set: Union Find Tree 并查集
知识点 并查集(Disjoint Sets):用互质集合(一个元素不同时包含于多个集合的集合)对数据进行分类管理的数据结构,包含的操作:makeSet(x):创建仅包含元素x的新集合findSet(x):求包含元素x的集合的代表元素(representative)unite(x,y),合并指定的元素x,y - 在并查集中,查询指定两个元素x,y是否包含于同一集合的操作称为Union F原创 2017-12-31 00:55:37 · 328 阅读 · 0 评论 -
第十三章 ALDS1_12_C:Single Source Shortest Path II 单源最短路径
问题链接ALDS1_12_C:Single Source Shortest Path II问题内容 求出顶点0到各边的最短路径思路 由于n比较大,所以需要用vector来处理数组,同时每条边都有权值,所以用vector代码#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <v原创 2017-12-31 00:54:35 · 878 阅读 · 0 评论 -
第十三章 ALDS1_12_B:Single Source Shortest Path I 单源最短路径
知识点 最短路径:对于加权图G=(V,E)中,求给定顶点s、d之间各边权值总和最小的路径。 单源最短路径(Single Source Shortest Path,SSSP):在图G中,求给定顶点u到其他所有顶点did_i之间的最短路径 全点对间最短路径(All Pairs Shortest Path ,APSP):在图G中,求任意两个顶点之间的最短路径dijkstra算法初始化状原创 2017-12-31 00:53:40 · 878 阅读 · 0 评论 -
第十三章 ALDS1_12_A:Minimum Spanning Tree 最小生成树
知识点树是没有环的图在树中,任意顶点r和顶点v之间必然存在着1条路径生成树:拥有图G的所有顶点,并且在保证自身是树的前提下拥有尽量多的边。最小生成树(MST):个边权值总和最小的生成树普里姆算法 设图G(V,E)所有顶点的集合为V,MST中的顶点的集合为T。从G中选取任意顶点r作为MST的根,将其添加到T。循环执行下述处理,直到T=V。在连接T内顶点与V-T内顶点的边中选取权值最小的原创 2017-12-30 16:18:52 · 666 阅读 · 0 评论 -
第十二章 ALDS1_11_D:Connected Components 连通分量
知识点 连通分量:连通性未知的图G,其极大连通子图即为G的连通分量。问题链接ALDS1_11_D:Connected Components问题内容 求出两个人能不能通过他们的朋友互相认识对方。思路 用广度优先搜索或者深度优先搜索计算全部人两两之间能不能称为朋友。利用连通分量的性质去将每个不同分量标记为不同的数字即可。代码#include <iostream>#include <c原创 2017-12-30 15:57:04 · 928 阅读 · 0 评论 -
第十二章 ALDS1_11_C:Breadth First Search 广度优先搜索
知识点广度优先搜索将起点s放入到队列Q中只要Q不为空,就循环执行下述处理 从Q中取出顶点u进行访问将与u相邻的未访问结点v放入到Q中问题链接ALDS1_11_C:Breadth First Search问题内容 求顶点1到其他点的最短路径长度,如果不能达到则输出-1思路 利用广度优先搜索,当访问u的边时,将d[v]更新为d[u]+1,则可以记录最短路径长度代码#include原创 2017-12-30 15:22:53 · 809 阅读 · 0 评论 -
第十二章 ALDS1_11_B:Depth First Search 深度优先搜索
知识点深度优先搜索将最初访问的顶点压入栈只要栈中还有顶点,就循环进行下面的步骤 访问栈顶部的顶点u,并删除u结点若当前u与v有边,且v未访问过,则将v压入栈中,并标记v已经被访问过。问题链接ALDS1_11_B:Depth First Search问题内容 求出每个结点压入栈的时间和出栈的时间思路 递归进行深度优先搜索,当压入一个结点后,时间加1,然后访问这个结点,赋值到压栈时间原创 2017-12-30 15:10:17 · 823 阅读 · 0 评论 -
第十二章 ALDS1_11_A:Graph 图的表示
知识点概念:对象集合以及其间关系的集合。 “对象”称为结点(Node)或者顶点(Vertex)“关系”表示顶点与顶点间的关系,称为边(Edge)种类 无向图:边没有方向的图有向图:边有方向的图加权无向图:边有权(值)没有方向的图加权有向图:边有权(值)有方向的图性质 相邻:无向图中存在边(u,v),则称顶点u和顶点v相邻路径:相邻顶点的序列v0,v1,...vkv_0,v_1,原创 2017-12-30 14:40:15 · 851 阅读 · 0 评论 -
第十一章 ALDS1_10_B:Matrix Chain Multiplication 矩阵链乘法
问题链接ALDS1_10_B:Matrix Chain Multiplication问题内容 求矩阵相乘计算次数最少的运算顺序,输出最少的次数。思路 如果l*m的矩阵与m*n的矩阵相乘则需要计算l*m*n次乘法运算。 通过多个矩阵的演算可以得知 m[i][j]=mini≤k≤j(m[i][k]+m[k+1][j]+p[i−1]∗p[k]∗p[j])m[i][j] = min_{原创 2017-12-30 12:41:47 · 925 阅读 · 0 评论 -
第十一章 ALDS1_10_C:Longest Common Subsequence 最长公共子序列
知识点 最长公共子序列(Longest Common Subsequence),简称LCS问题。假设现在有两个序列X,Y。那么他们的子序列中相同且长度最大的子序列则称为X,Y的最长公共子序列。问题链接ALDS1_10_C:Longest Common Subsequence问题内容 求两个字符中最长公共子序列思路 利用斐波那契数列的递推关系,可以联想到。 当Xi=YjX_i=Y原创 2017-12-30 12:03:39 · 322 阅读 · 0 评论 -
第十一章 ALDS1_10_A:Fibonacci Number 斐波那契数列
问题链接ALDS1_10_A:Fibonacci Number问题内容 求出斐波那契数列的第n项的值。思路 递推并记录前n项的值到数组,求第n项的值时用到第n-1项和第n-2项,这样我们先记录开始的值,然后就可以在求后面的值时直接利用即可并同时记录下来以便后面的使用。由于n的值比较小,所以一次性计算出来。代码#include <iostream>#include <cstdio>us原创 2017-12-30 11:38:24 · 326 阅读 · 0 评论 -
第十章 ALDS1_9_C:Priority Queue 优先队列
知识点 优先队列:优先取出最大键值的队列,可以利用最大堆实现、也可以用STL实现。问题链接ALDS1_9_C:Priority Queue问题内容 对于队列有两种操作,insert(S,k)在集合S中插入元素k;extract()将队列键值最大的值取出。end()结束处理。思路 对于insert操作,将元素k插入到最大堆的最后一位,然后往上比较交换即可;对于extract操作,删除第原创 2017-12-30 11:31:08 · 802 阅读 · 0 评论 -
第十章 ALDS1_9_B: Maximum Heap 最大堆
知识点 最大堆:对于所有的结点i,其键值小于等于其父结点的键值问题链接ALDS1_9_B: Maximum Heap问题内容 对于数列A,利用最大堆的性质,将数列实现成最大堆思路 对于含有n各元素的数列A。i从n/2为起点,以1为终点遍历。每次执行maxHeapify,即是往下和左右结点比较,若比子结点大,则交换,直到无法比较。代码实现最大堆的功能#include <iostrea原创 2017-12-30 11:06:48 · 784 阅读 · 0 评论 -
第十章 ALDS1_9_A:Complete Binary Tree 完全二叉树
知识点完全二叉树:二叉树的叶结点深度最大差距为1,最下层叶结点都集中在该层最左边的若干位置。 树高是log2nlog_2n最下层的叶结点都是从左往右满满得集中在左侧且中间没有空置的。满二叉树:叶结点的深度全部相同,对于每个结点,要么有两个子结点,要么是叶结点。 对于n层的满二叉树(从1开始),整个树有2n−12^n-1个结点。要么是叶结点,要么是含有两个子结点的内部结点满二叉树一种比较原创 2017-12-30 10:40:58 · 886 阅读 · 0 评论 -
第九章 ALDS1_8_C:Binary Search Tree III 二叉搜索树--删除
问题链接ALDS1_8_C:Binary Search Tree III问题内容 在上一篇的基础上加上删除的功能思路 删除功能需要考虑三种情况,假设删除的结点为x (1)x没有子结点,则将x结点删除即可 (2)如果x只有左子树或者只有右子树,则将子树拼接上父结点即可 (3)如果同时具有左右子树。可以有两种做法: 其一是令x的左子树为f的左/右(依x是f的左子树还是右原创 2017-12-27 22:25:44 · 413 阅读 · 5 评论 -
第九章 ALDS1_8_B:Binary Search Tree II 二叉搜索树--搜索
问题链接ALDS1_8_B:Binary Search Tree II问题内容 在上一个题目加多搜索功能思路 对于搜索功能,从根结点往下遍历即可。代码#include<iostream>#include<cstdio>using namespace std;const int MAX = 100005;struct Node { int key; Node *pa原创 2017-12-27 20:47:06 · 249 阅读 · 0 评论 -
第九章 ALDS1_8_A:Binary Search Tree I 二叉搜索树--插入
知识点 二叉搜索树:设x为二叉搜索树的结点,如果y为x的左子树中的结点,那么y的值小于等于x;同理,若在x的右子树,则y的值大于等于x。问题链接ALDS1_8_A:Binary Search Tree I问题内容 insert是插入操作,print是输出中序和前序遍历结果的操作思路 按照题目的伪代码提示去构建,前序中序遍历用前面的例子代码即可。代码原创 2017-12-27 20:33:03 · 344 阅读 · 0 评论 -
第八章 ALDS1_7_D:Reconstruction of a Tree 树的重建
问题链接ALDS1_7_D:Reconstruction of a Tree问题内容 给出前序数组和中序数组,求后序数组思路 在当前前序数组的第一个元素pre[pos++],找出它在中序数组的下标m,然后根据中序数组的性质(左、根、右遍历的性质)分出左子树和右子树,所以进行递归下去求左右子树的根,最后根据后序数组的性质(左、右、根)可以直接存到post数组。代码#include<iost原创 2017-12-27 19:58:28 · 338 阅读 · 0 评论 -
第八章 ALDS1_7_C:Tree Walk 树的遍历
知识点树的遍历方法:前序遍历,中序遍历和后序遍历前序遍历 按照根结点、左子树、右子树的顺序输出结点编码。 中序遍历 按照左子树、根结点、右子树的顺序输出结点编码。后序遍历 按照左子树、右子树、根结点的顺序输出结点编码。问题链接ALDS1_7_C:Tree Walk问题内容 对于给出的二叉树,分别求出前序遍历,中序遍历和后序遍历。思路 利用递归的思想可以很优雅得写出这几个遍历方原创 2017-12-27 00:32:47 · 393 阅读 · 0 评论 -
第八章 ALDS1_7_B:Binary Trees 二叉树
知识点问题链接ALDS1_7_B:Binary Trees问题内容对于给定的二叉树,输出各结点u的信息,信心包括u的结点编号,u的深度,u的父结点,u的高,u的兄弟结点,结点的种类(根、内部结点、叶)、u的子结点数思路代码原创 2017-12-26 23:25:51 · 280 阅读 · 0 评论 -
第八章 ALDS1_7_A:Rooted Trees 有根树
知识点左子右兄弟 表示法(leaf-child right-sibling representation)结点信息 结点u的父结点 parent属性结点u最最侧的子结点 left属性结点u右侧紧邻的兄弟结点 right属性性质 不存父结点的就是根不存在u.left的结点就是叶(leaf)不存在u.right的结点为最右侧子结点 问题链接ALDS1_7_A:Rooted Trees问原创 2017-12-26 23:24:02 · 387 阅读 · 0 评论 -
第八章 树结构
由于接下来三章内容都是讲解树相关的算法,这篇主要针对树的概念进行定义。树概念 由结点(node)以及连接结点的边(edge)构成的数据结构有根树概念具有一个名为“根”(root)的特殊节点的树性质结点之间有父子关系在有根树从根r到结点x的路径上最后一条边连接着结点p与结点x,那么称p是x的父结点(parent),x是p的子结点(child) 同一个父结点的不同子结点之间称为兄弟结点原创 2017-12-26 21:40:05 · 205 阅读 · 0 评论 -
第七章 ALDS1_6_D:Minimum Cost Sort 最小成本排序
问题链接ALDS1_6_D:Minimum Cost Sort问题内容 排序过程中,排序的成本等于累加每次交换元素的和。思路 利用置换群的思想去做(就是一个简单的循环),根据演算的结果求出最小值代码#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;con原创 2017-12-26 20:39:31 · 661 阅读 · 0 评论