专题汇总
A-棋盘问题
简单的dfs,这里使用了嵌套的递归。外层为源起,始终指向本方案的第一个棋子;内层为终点,指向本方案最后一个棋子,同时结合hash数组打表来区别不同的方案。
教训就是,全局变量和递归的思想是冲突的。
B-Dungeon Master
6个方向的bfs
C-Catch That Cow
简单的bfs
D-FlipTile
这题有两点:
一是要找到规律
第i-1行第j个瓷砖的状态受它四周及本身的翻转次数影响。
- 翻转次数之和加上自身状态是偶数,则不需要翻转
- 翻转次数之和加上自身状态是奇数,则不需要翻转
二是使用了二进制枚举,使得枚举这部分代码变得简洁。
仍然是一个简单的dfs
E-Find The Multiple
这题很水,dfs和bfs都可以。
在这题得到的教训是,能用stl容器,就别自己写数据结构。
F-Prime Path
简单的bfs,结合素数筛打表。
G-Shuffle’m Up
退化的dfs和bfs,主要是模拟以及看清题意。
H-Pots
简单的bfs,加上状态的保存和检索状态变化。
I-Fire Game
双起点的bfs,两起点的关系是合作遍历的关系。
J-Fire!
要注意的地方在于,火源是复数个。
两次bfs。一前一后,人必须赶到火前面,是竞争关系。
K-迷宫问题
bfs+状态保存
L-Oil Deposits
水题,8个方向的bfs
M-非常可乐
12个方向的bfs,一定要细心
N-Find a way
两次bfs,结果累加。
教训是,bfs是个十分方便的工具,但如何去使用,结构也是决定程序效率的一个关键因素。
总结
这是我做的第一个专题,充分暴露了我代码力不足的缺点。这里不管是多简单的题,我都是累积3个小时以上才AC的。有很多细节,我没有顾及到。比如,J题中的多火源以及人与火之间的关系,我都没有考虑清楚。还需要继续努力。
bfs和dfs很简单,但是他们的应用很灵活。
对dfs来说,你可以在对整个图的遍历中不断的调用dfs,最终得到想要的结果(比如D题),这是暴力求最优解;你还可以将它嵌套,dfs本就是对所有分支遍历直至末节,这是对可行方案数的枚举(比如A题)。
对bfs来说,你可以增加“方向”,也就是增加对每个结点的处理方式(比如B、L和M题等),这仍然是基础的bfs;你也可以增加遍历的起点,起点们之间是合作遍历的关系(如I题);你还可以增加bfs的次数,先后有序,相互竞争,互为约束(如J题);你还可以对结点状态进行保存以输出可行方案的具体操作(比如H和K题),这是回溯,可以使用链表的思想或者借助数组使用递归代替,本质是一样的。