![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
挑战程序设计竞赛2 算法和数据结构
文章平均质量分 51
小酷miki
这个作者很懒,什么都没留下…
展开
-
挑战程序设计竞赛2 算法和数据结构 读后感
介绍 本篇主要是讲《挑战程序设计竞赛2 算法和数据结构》书的读后感和部分题目的再次解读、编程。包括书中的部分代码和一些个人的见解。如果想深入了解,建议去网上买一本回来看,比较适合学习算法的初学者。章节第一章 第一章主要让你在AOJ处注册登录,然后开始做题第二章2.5 入门问题 ALDS1_1_D:Maximum Profit第三章 初等排序...原创 2017-12-21 22:22:48 · 5064 阅读 · 3 评论 -
第六章 ALDS1_5_A:Exhaustive Search 穷举搜索
问题链接 ALDS1_5_A:Exhaustive Search问题内容 判断长度为n的数列A中任意几个元素相加能否得到m思路对于A的每一个元素都有“选”和“不选”的情况,由于n比较小,我们通过递归穷举每个元素选和不选的情况,当得到m就返回。代码#include<iostream>#include<cstdio>using namespace std;int n, A[30];//原创 2017-12-21 22:41:18 · 1244 阅读 · 0 评论 -
第九章 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 · 236 阅读 · 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 · 329 阅读 · 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 · 324 阅读 · 0 评论 -
第八章 ALDS1_7_C:Tree Walk 树的遍历
知识点树的遍历方法:前序遍历,中序遍历和后序遍历前序遍历 按照根结点、左子树、右子树的顺序输出结点编码。 中序遍历 按照左子树、根结点、右子树的顺序输出结点编码。后序遍历 按照左子树、右子树、根结点的顺序输出结点编码。问题链接ALDS1_7_C:Tree Walk问题内容 对于给出的二叉树,分别求出前序遍历,中序遍历和后序遍历。思路 利用递归的思想可以很优雅得写出这几个遍历方原创 2017-12-27 00:32:47 · 376 阅读 · 0 评论 -
第八章 ALDS1_7_B:Binary Trees 二叉树
知识点问题链接ALDS1_7_B:Binary Trees问题内容对于给定的二叉树,输出各结点u的信息,信心包括u的结点编号,u的深度,u的父结点,u的高,u的兄弟结点,结点的种类(根、内部结点、叶)、u的子结点数思路代码原创 2017-12-26 23:25:51 · 267 阅读 · 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 · 374 阅读 · 0 评论 -
第八章 树结构
由于接下来三章内容都是讲解树相关的算法,这篇主要针对树的概念进行定义。树概念 由结点(node)以及连接结点的边(edge)构成的数据结构有根树概念具有一个名为“根”(root)的特殊节点的树性质结点之间有父子关系在有根树从根r到结点x的路径上最后一条边连接着结点p与结点x,那么称p是x的父结点(parent),x是p的子结点(child) 同一个父结点的不同子结点之间称为兄弟结点原创 2017-12-26 21:40:05 · 193 阅读 · 0 评论 -
第七章 ALDS1_5_D:The Number of Inversions 逆序数
知识点 如果一组数(i,j)满足ai>aja_i>a_j并且i<ji < j ,那么称这组数是一个逆序问题链接ALDS1_5_D The Number of Inversions问题内容 求数列的逆序数思路 利用归并排序,在合并两个局部数组时,计算R数组n1-i,就可以知道L会有多少元素往R[j]后面移动了,就是相关的逆序数。代码#include<iostream>#includ原创 2017-12-26 19:56:02 · 304 阅读 · 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 · 648 阅读 · 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 · 374 阅读 · 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 · 242 阅读 · 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 · 306 阅读 · 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 · 406 阅读 · 5 评论 -
第十七章 DPL_3_B: Largest Rectangle 最大长方形
问题链接DPL_3_B: Largest Rectangle问题内容 求最大的干净面积。0代表干净,1代表有污渍。和上一不同的是,这个题目面积可以是长方形的。思路 首先通过以行为直方图,以行为第一遍历,纵向记录每个点当前的最大面积。然后从行向开始动态规划。 利用栈实现。如果栈为空,将当前元素压入栈中。如果栈顶元素的高度(上面一步计算出来的纵向最大面积)小于当前的高度,则压入栈中。如果原创 2018-01-04 21:27:45 · 338 阅读 · 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 · 310 阅读 · 0 评论 -
第十二章 ALDS1_11_D:Connected Components 连通分量
知识点 连通分量:连通性未知的图G,其极大连通子图即为G的连通分量。问题链接ALDS1_11_D:Connected Components问题内容 求出两个人能不能通过他们的朋友互相认识对方。思路 用广度优先搜索或者深度优先搜索计算全部人两两之间能不能称为朋友。利用连通分量的性质去将每个不同分量标记为不同的数字即可。代码#include <iostream>#include <c原创 2017-12-30 15:57:04 · 912 阅读 · 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 · 800 阅读 · 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 · 819 阅读 · 0 评论 -
第十二章 ALDS1_11_A:Graph 图的表示
知识点概念:对象集合以及其间关系的集合。 “对象”称为结点(Node)或者顶点(Vertex)“关系”表示顶点与顶点间的关系,称为边(Edge)种类 无向图:边没有方向的图有向图:边有方向的图加权无向图:边有权(值)没有方向的图加权有向图:边有权(值)有方向的图性质 相邻:无向图中存在边(u,v),则称顶点u和顶点v相邻路径:相邻顶点的序列v0,v1,...vkv_0,v_1,原创 2017-12-30 14:40:15 · 838 阅读 · 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 · 912 阅读 · 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 · 309 阅读 · 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 · 313 阅读 · 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 · 795 阅读 · 0 评论 -
第十章 ALDS1_9_A:Complete Binary Tree 完全二叉树
知识点完全二叉树:二叉树的叶结点深度最大差距为1,最下层叶结点都集中在该层最左边的若干位置。 树高是log2nlog_2n最下层的叶结点都是从左往右满满得集中在左侧且中间没有空置的。满二叉树:叶结点的深度全部相同,对于每个结点,要么有两个子结点,要么是叶结点。 对于n层的满二叉树(从1开始),整个树有2n−12^n-1个结点。要么是叶结点,要么是含有两个子结点的内部结点满二叉树一种比较原创 2017-12-30 10:40:58 · 874 阅读 · 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 · 771 阅读 · 0 评论 -
第十九章 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 · 690 阅读 · 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 · 475 阅读 · 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 · 564 阅读 · 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 · 402 阅读 · 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 · 455 阅读 · 0 评论 -
第五章 ALDS1_4_B Binary Search 二分搜索
知识点 对于已经排序好的数列,我们可以使用二分搜索法更快速找到key。 初始:left = 0 , right = n,先通过key和位置mid = (left + right) / 2的元素比较,若key < A[mid] ,则设置right = mid;若key > A[mid],则设置left =mid +1;不断缩小范围重复上面的步骤直到key或者结束搜索。 问题链接ALDS1_原创 2017-12-24 15:06:15 · 300 阅读 · 0 评论 -
第五章 ALDS1_4_C:Dictionary 散列表
知识点链表概念 根据元素的值通过某种运算(通过函数计算出相应的值)确定元素的存储位置,然后将元素保存到相应的位置。插入、搜索、删除都是通过函数计算出相应的值,再根据值去到存储位置进行操作,这些过程基本是O(1)O(1)的操作。计算函数尽量能将各种值存储在不同的位置,但是也有总有“冲突”(不同的值计算出来的结果一样的情况),这时候需要解决冲突的方法:开放地址法(数组)、拉链法(链表)实现方法原创 2017-12-24 16:31:13 · 456 阅读 · 1 评论 -
第五章 ALDS1_4_A:Linear Search 线性搜索
知识点 线性搜索比较简单,就是从数列的第一个位置开始往后找,直到找到指点的元素,单次搜索的复杂度是O(n)O(n)问题链接ALDS1_4_A:Linear Search问题内容 对于包含n个整数的数列S,查询包含q个不重复元素的T数列中有多少个在数列S中,求出总数。思路 采用线性搜索的思路去写即可。循环遍历T数组,在S数组中找到指定的元素,时间复杂度是O(qn)O(qn),为了减少计原创 2017-12-24 14:26:49 · 475 阅读 · 0 评论 -
第四章 ALDS1_3_D:Areas on the Cross-Section Diagram
问题链接ALDS1_3_D:Areas on the Cross-Section Diagram问题内容 求出每个积水处的横截面积思路 利用栈的思想去做如果是’\’则将该字符的位置i压入栈如果是’/’则从栈顶取出与之对应的’\’的位置ipi_p累加两者距离i−ipi-i_p,结果即为总面积代码#include<iostream>#include<cstdio>#include<c原创 2017-12-24 02:23:30 · 629 阅读 · 0 评论 -
第四章 ALDS1_3_C:Doubly Linked List 链表
知识点 链表链表类型 单向链表: 数据本体和指向后一元素的指针next双向链表: 数据本体、指向前一元素的指针prev和指向后一元素的指针next循环链表: 在单向链表或者双向链表的前提下加上循环利用数组的机制的链表STL的list类(双向链表)的成员函数 size():返回表的元素数begin():返回指向表开头的迭代器end():返回表末尾的迭代器push_front(x):原创 2017-12-24 01:57:43 · 406 阅读 · 0 评论 -
第四章 ALDS1_3_B:Queue 队列
知识点 队列 规则:先入先出(First In First Out) 操作 enqueue(x):在队列末尾添加元素x dequeue():从队列开头取出元素 isEmpty():检查队列是否为空 isFull():检查队列是否已满 STL的queue类的成员函数,都是O(1)操作 size():返回队列的元素数 front():返回队头的元素原创 2017-12-24 00:43:18 · 380 阅读 · 0 评论 -
第四章 ALDS1_3_A:Stack 栈
知识点栈规则:后入先出(Last In First Out)基本操作: push(x):在栈顶部添加元素xpop():在栈顶部取出元素isEmpty():检查栈是否为空isFull():检查栈是否已满STL中的stack类的成员函数,都是O(1)操作 size():返回栈的元素数top():返回栈顶的元素pop():从栈中取出并删除元素push(x):向栈中添加元素xempt原创 2017-12-23 23:52:31 · 550 阅读 · 0 评论 -
第三章 ALDS1_2_D:Shell Sort 希尔排序法
知识点 希尔排序法是基于插入排序法 每次以间隔为g的元素为对象进行的插入排序,然后不断缩小g,然后继续插入排序,直到g=1.小结 时间复杂度是O(n1.25)O(n^{1.25}),空间复杂度为O(n)O(n),是不稳定排序。问题链接ALDS1_2_D:Shell Sort问题内容 输出g的选择数量,然后输出g数组,然后输出交换次数,最后输出排序后的结果。思路 根据数量n原创 2017-12-23 02:01:25 · 504 阅读 · 0 评论