Last updated
Last updated
官方的介绍网站:
乙级要求:1. 基本的C/C++的代码设计能力,以及相关开发环境的基本调试技巧;
2. 理解并掌握最基本的数据存储结构,即:数组、链表;
3. 理解并熟练编程实现与基本数据结构相关的基础算法,包括递归、排序、查找等;
4. 能够分析算法的时间复杂度、空间复杂度和算法稳定性;
5. 具备问题抽象和建模的初步能力,并能够用所学方法解决实际问题。
在达到乙级要求的基础上,还要求:1. 具有充分的英文阅读理解能力;
2. 理解并掌握基础数据结构,包括:线性表、树、图;
3. 理解并熟练编程实现经典高级算法,包括哈希映射、并查集、最短路径、拓扑排序、关键路径、贪心、深度优先搜索、广度优先搜索、回溯剪枝等;
4. 具备较强的问题抽象和建模能力,能实现对复杂实际问题的模拟求解。
甲级题目中大部分考察的静态链表,也就是使用数组的index作为指针。
考察题目:
第2道题参考了柳神的做法,用了一个取巧的办法,实际并没有对链表进行实质意义上的排序,而是记录了每个节点的自身的地址,实际上并没有对节点的地址进行调整。
对于二叉树的遍历方式有三种分别是:
前序(先序):根左右(根节点,左孩子,右孩子)
中序:左根右(左孩子,根节点,右孩子),如果是二叉搜索树,这个访问结果序列为有序序列
后序:左右根(左孩子,右孩子,根节点)
不加证明地给出,已知前序中序,或者中序后序可以唯一确定一颗二叉树,给定前序后序则不一定可以唯一确定一颗二叉树。
考察题目:
第3道题比较“含蓄”地给出前序和中序,前序是其PUSH的序列,而中序是POP的序列。
代码实例:
考察题目:
这道题的要求是输出后序访问中的第一个元素,参考柳神的代码中,我们可以得到不需要构建二叉树,直接输出这颗二叉树的后序思路,具体如下:
考察题目:
考察的题目有:
首先对于“传统”思路建树,找结点路径,判断公共祖先,这个方法是肯定要会的,但是对于具体的题目,会有一些更为优化的算法。
这两道题中,第一道题采用,构建树,寻找两个节点的路径,在比较路径中的结点得到最近公共祖先会导致后面三个测试点超时,而第二道题使用上面这个思路则不会超时。
补充得到树的root节点到叶子节点路径的方法:(下面这个查找到指定节点的路径)
dfs+dijkstra 1087.All Roads Lead to Rome (30分)
考察题型:
这两道题的核心是最大公约数的求法,使用辗转相除法
考察题目:
注意的要点是,当H(key)被占用的时候,下一次的探测位置的计算公式为H(key) + k^2,和H(key) - k^2的平方,如果超过了哈希表的长度,那么就需要对表长取模。那么探测的次数要几次呢,如果一直没找到什么时候退出?这里的判断标准是k落在[0, tsize]内,如果k大于ksize时,一定无法找到了。
注意:这里查找的判断的范围是闭区间,[0, tsize],插入是[0, tsize)
考察题目:
关于排序,基本排序算法基本不会让你自己实现,所以对于选择排序,插入排序,快速排序这些,只需了解基本思想,能够知道实现流程即可。可能考察的题型,是链表的排序,就需要用到选择排序,或者插入排序的思想,因为链表不能直接跳转,无法直接使用sort函数。
考察题型:
考察的题型有:
这两道题都是给定了两个序列,一个是未排序初始序列,另一个是排序为完成的序列,判断是采用哪种排序方式,然后给出下一轮次的排序结果。
判断是否是插入排序的方法:
这两道题可以选择取巧的方式,因为只判断两种排序方式,不是其中一种,那就一定是另外一种了,所以只需要判断一种排序方式即可,相比之下,插入排序的判断方式是比较快的,所以只要判断是否是插入排序,不是的话一定就是另外一种排序方式了。
这三道题的类型一致,都是深度优先搜索,只不过根据题目的要求不同判断条件不同,万变不离其宗,可以对比着学习。
n件物品,每件物品的重量为w[i],价值为c[i],现在要选出若干件物品放入一个容量为V的背包中,使得选入背包的物品重量不超过容量V的前提下,让背包中共的物品价值最大。
总结:这个问题给了一类常见的DFS问题的解决办法,即给定一个序列,枚举这个序列的所有子序列(可以不连续)。
比如说,从N个整数中选择K个数,使得这个K个数的和为X,如果有多个方案,选择元素平方和最大的一个。
给定一个数组为1~N,如果输出它的全排列呢?(《算法笔记》P115)
拓展问题:如何输出给定数据的全排列呢?例如输入['a', 'b', 'c'],[11, 12, 13],我的思路:既然我们可以求出1~N的全排列,把这些全排列作为index下面,然后依据下标index输出输入的['a', 'b', 'c']即可。
这道题难度不大,核心就是判断N皇后的位置不在对角线以及同一行即可。
简单概述下N皇后问题,就是将N皇后放在N×N的棋盘上,要求是皇后不能处在同一排,同一列以及对角线上,目标是求出这样的排列方式有哪些。
这个问题为什么和全排列有关系呢,是这样的,每个N皇后的摆放位置可以是1N的位置,那么在棋牌上从左到右来看的话,就是每个皇后的位置都是从1~N中选择一个数值,这样满足了不是同一列,那么为了满足不是同一排,那么每个皇后选择的位置是不同的,这样得到的最终数值就是一个全排列,现在唯一不满的就是对角线了,所以只需要在全排列代码的基础上判断不处于对角线即可。
输出两个日期的差值,两个日期之间相差多少天,思路是对小的日期进行++,直到等于大的日期。
2. i++和++i
在代码里面,我们可以看到for循环的第三个表达式有两种写法,i++和++i,那么这两个区别是什么呢,要用哪一个呢?结论是用哪一个都可以,但是效率上有一点点差别,但是随着现代编译器和计算机性能的发展,这个差别几乎可以不考虑。那么差别在哪里呢?
3. map的神奇之处
map可以直接访问未插入的元素,比如下面的代码:
4. 数值的表示范围
题目中会给出数据的取值范围,我们需要判断相应的变量类型是否可以放得下,所以记住各个变量的表示范围是很有必要的。题目中一般给的是10的几次方的形式,所以大致范围需要重点关注。其他类型属于常规,可直接参考《算法笔记》P7.
5. 输入一行单词的小技巧
6. 什么叫做剪枝?
和这个相关的有几个说法:
暴力法:枚举所有的情况,然后判断每一种情况是否合法,这种做法是非常朴素的,没有优化的算法
回溯法:如果到达递归边界的某层,由于一些事情导致已经不需要往任何一个子问题递归,就可以直接返回上一层,这种做法称之为回溯法
剪枝:在DFS中,通过题目限制条件来减少DFS计算量的方法称之为剪枝。至于为什么叫做剪枝,是因为DFS的遍历就如果如果树的先根遍历,剪枝就是去掉不满足条件的子树,所以称之为剪枝。《算法笔记》P305
7. STL中queue的注意事项
8. 要点
要注意数据的取值范围!选择正确的数据类型!
注意数据中是否可能出现重复数据,使用大于小于,还是大于等于,小于等于
注意下标是从0开始还是从1开始!
使用printf和scanf进行输出输入,时间和cin和cout差别很大!尽量不适用cin和cout
《算法笔记》胡凡.曾磊.著
《算法笔记 - 上机训练实战指南》 胡凡.曾磊.著
PAT甲级考试总共有4道题,考察的类型分别如下(参考自浒鱼鱼的):
这道题的本质就是构建一颗平衡二叉树,然后输出它的根节点即可,具体的代码解释,请查看。
针对这两道题的解法都很巧妙,具体参考柳神的博客:和。
判断的思想是这样,一个元素能够作为pivot的条件是,序列的左半部分比pivot小,右半部分比pivot大,关键点在于,这个选为pivot的数值在一轮排序中是处于最后位置的,这个是这道题的核心。如果直接判断左半部分和右半部分满不满足条件的话,测试用例会超时,因为这样是的时间复杂度。
这道题的其他解法,参考: 。
利用公式,这部分内容挺多,直接参考《算法笔记》P183
使用scanf读入字符时要注意,前面加个空格,原因
浒鱼鱼的
题号
考察知识点
1
字符串、素数、数学问题
2
链表、Hash函数、排序
3
图、并查集、(平衡、搜索)二叉树
4
LCA、树、拓扑排序、Dijkstra、堆
序号
类型
题目
1
找到单词链表的共同后缀
2
对链表进行排序
序号
类型
题目
1
依据后序中序输出前序
2
给定前序后序输出中序(不一定唯一)
3
给定前序中序,输出后序
序号
类型
题目
1
给定前序中序,输出后序
序号
类型
题目
1
求解平衡二叉树的根节点
2
创建平衡二叉树+判断完全二叉树
3
创建一颗二叉搜索树
序号
类型
题目
1
找到每个人归属的社群
2
计算家族房产
3
判断鸟儿是否属于同一棵树
序号
类型
题目
1
寻找最近公共祖先
2
寻找最近公共祖先
序号
类型
题目
1
判断是否为序列是否满足拓扑排序
序号
类型
题目
1
有理数分数求和
2
有理数分数四则运算
序号
类型
题目
1
将数值分解成质因子相乘
序号
类型
题目
1145
哈希表-平方探测
序号
类型
题目
1
判断序列元素是否可以作为pivot
序号
类型
题目
1
判断是否是插入排序,归并排序的序列
2
判断是否是插入排序,堆排序的序列
序号
类型
题目
1
供应链所有价格
2
供应链最大价格
3
供应链最小价格
序号
类型
题目
1
判断是否满足N皇后的排列序列
类型
取值范围
大致范围
int
-2147483548~+2147483647(~)
~
long long
~
~