紫书就是刘汝佳的《算法竞赛入门经典(第二版)》。前5章被我跳了(写模拟WA到怀疑人生),这是做第6章题目的经历和心得。
本章我的代码见github。
6.1节例题6-1 uva210
lock失败的这个指令在加入block列表的同时应当保留而不是跳过这个指令,这里WA2次。
6.2节例题6-5 uva12657
对于交换两个相邻位置的盒子时应该单独处理,这里TLE6次,但这个单独处理没什么根据,怀疑是标程针对测试数据的特殊策略。
6.3节例题6-7 uva122
这题可以不按照书上建树的方法做。先判断有没有路径重复的,再判断非空路径去掉最后一位后是否存在对应节点,从而排除不完全的情况。然后以长度为第一关键字,字典序为第二关键字排序,按序输出即可。
起初我是先排序,然后枚举查找判断是否完全的,但莫名其妙地WA7次。后来改成用set<string>来判重、找父节点,就AC了。
6.4节例题6-14 uva816
BFS队列大小开的是400结果开小了RE1次,后来改成100000。
6.4节例题6-16 uva10129
6.5节例题6-19 uva1572
因为标记节点存在性的use[i]本来是+,-共用一个位置的(即use[i%26]),但写程序的时候忘了导致RE1次。这题的做法不看题解真的很难想出来。
★6.5节例题6-20 uva1599
一开始想正向BFS发现不可行,便按照书上的算法来写。WA了6次,前几次是因为第二次BFS应该先找出最小字典序再把对应的所有可能情况入队而不是边入队边比较最小值(那样会把不是最小字典序的方案入队),后来是因为用数组存图的各边然后排序做成邻接链表的样子结果不对劲(具体错误原因不明),改成了真正的模拟链表(还顺便把第二次BFS从手动写队列改成了和标程一样的vector)。
习题6-1 ua673
习题6-2 uva712
习题6-5 uva1600
BFS一次即可。
习题6-6 uva12166
平衡状态下每个结点值*2深度是定值。本来想枚举以哪一个节点为标准,后来发现直接将结点值*2深度存起来,用map统计出现最多的那个值即可。
习题6-7 uva804
模拟即可,不会超时。
习题6-8 uva806
依然模拟即可,可以用递归,不会超时。
习题6-12 uva810
BFS。对于骰子移动后顶、正面的变化处理比较麻烦。
习题6-13 uva215
用DFS找出所有有向环上的节点,如果是DAG就再DFS一遍算出所有单元格的值即可。因为末尾要有一个空行以及每个单元格占6个字符所以PE3次。
★习题6-14 uva12118
这题一开始用DFS做,TLE(实际上自己的算法也有问题),故搜题解。题目可以转化为已知一个无向图(无重边和自环),让你添加最少的边(可以有重边但不可以有自环),使得整个图形成一条欧拉路。于是用DFS找出原图的各个连通块,连通块内部如果奇数点个数nodd多于2个就要补充nodd/2-1条边使这个块成为欧拉路,此外m个连通块之间还要补充m-1条边使其相互连接。
做题时还有几个细节错误:1.得到的边数要乘以T才是答案 2.注意清空上一轮的数据 3.e=0时连通块个数m=0,要单独处理 以上各WA1次。