数学相关
Cantor 数表:将 Georg Cantor 用于证明有理数是可穷举的数表,拟合为一个列表(第一项是 1/1,第二项是 1/2,接着是 2/1、3/1、2/2、1/3…)。
求 Cantor 数表的第 n 项。
第 i 条线上有 i 个数。
果园里的树:树排列成矩阵,它们的 x/y 坐标均是 1-99 的整数。输入若干个三角形,依次统计每个三角形内部和边界上总共有多少棵树。
三角形的有向面积:$$\begin{pmatrix} x_0 & y_0 & 1 \ x_1 & y_1 & 1 \ x_2 & y_2 & 1 \end{pmatrix}$$
多少块土地:你有一块椭圆形的地,在边界上选取 n 个点,两两连接得到 $$\displaystyle \frac{n(n-1)}{2}$$ 条线段,它们最多能把土地分成多少个部分。
欧拉公式:V - E + F = 2
;
图相关
岛屿问题
DFS (Depth-First Search, DFS): 深度优先遍历。
迷宫问题
BFS (Breadth-First Search): 广度优先遍历。
可以构造一个以起点为根节点的树状结构。
拓扑排序 (topological sort):对于 n 个变量,m 个二元组 (u, v) 表示 u < v:把每个变量看成一个点,每个二元组看成一条有向边,把一个图的所有节点进行排序,使得有向边的 u 都在 v 的前面,这个过程称为拓扑排序。
有向无环图 (Directed Acyclic Graph, DAG)
欧拉回路
暴力法
回溯法
八皇后问题
回溯法 (backtracking)。
素数环:输入正整数 n,把 1-n 组成一个环,使得任意相邻两个数字的和为素数。
隐式图搜索
埃及分数:在古埃及,人们使用单位分数的和表示一切有理数。例如:2/3 = 1/2 + 1/6,但是不允许相同的加数出现,比如:2/3 = 1/3 + 1/3。对于一个分数 a/b,表示方法有很多种,其中加数越少越好,如果加数个数相同则最大的分母越小越好。
给定两个整数 a、b,求最佳表达式。
迭代加深搜索 (iterative deepening):从小到大枚举深度上限 d,每次只考虑深度不超过 d 的节点。
深度上限对于这个题目还可以用剪枝 (prune) 的思想,如果扩展到 i 层,前 i 的分数和为 c/d,而第 i 个分数为 1/e,那么接下来还需要 (a/b-c/d)/(1/e) 的分数。
倒水问题
假设每个水杯中盛放了一定量的水,认为是一种状态,那么我们可以构造出一个状态转移有向图。
八数码问题:编号为 1-8 的 8 个正方形被摆成 3 行 3 列。每次操作可以把与空格相邻的任意滑块移动到空格中,使得该滑块原来的位置成为新的空格。
如果给定初始局面和目标局面,计算出最少的移动步数。
每个状态认为是图的一个节点,上述问题就是图上的最短路问题。
高效算法
最大连续和。
$O(n^3)$ 算法:三层循环;
$O(n^2)$ 算法:设 $S_i$ 为前 i 项和,求解 $S_j - S_i$ 的最大值只需要两层循环;
$O(n log n)$ 算法:分治策略,前一半的最大、后一半的最大,起点在前面终点在后面的最大;
$O(n)$ 算法:迭代式计算以 n 结尾的最大连续和。
循环日程表问题
递归。
贪心算法
最优装载问题:给定 n 个物品的重量,选择尽量多的物体使得总重量不超过 C。
优先装载较轻的物品。
部分背包问题:给定 n 个物品的重量和价值,在总重量不超过 C 的情况下使得总价最高。每个物品可以只取走一部分,价值按比例计算。
优先取 “价值/重量” 最大的。
乘船问题:给定 n 个人的重量,每艘船承重 C,且最多只能乘两个人。用最少的船装载所有人。
从最轻的人开始,选择能跟他一起乘坐的人中,最重的人一起乘船。
选择不相交区间:给定 n 个开区间,选择尽量多的区间使得两两之间没有公共点。
按上限排序,从小到大选择。
区间选点问题:给定 n 个闭区间,取尽量少的点使得每个区间中至少有一个点。
按上限排序,直接选择区间的上限。
区间覆盖问题:给定 n 给闭区间,选择尽量少的闭区间完全覆盖给定线段;