Ryen的学习笔记

成长有多少新奇的美,就有多少撕裂的痛;离去有多么辽阔的自由,就有多么无边的孤寂。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

算法练习三(搜索部分)

Posted on 2010-02-03 11:24  Ryen_lee  阅读(640)  评论(0)    收藏  举报
  • ID Codes : next_permutation, STL水过,自己实现了个字符版本。
  • Birthday cake: 竟然使用随机数水过了,怪哉。
  • The Hamming Distance Problem(,729): 按字典序枚举排列,如果最后一行多输出空行会WA。
  • Island of Logic(1478,): 经典题,基本思想是枚举所有可能状态,根据输入判断。一个好的策略是用每条输入对所有状态进行筛选,矛盾的置零,则用所有输入进行筛选后剩余的状态即为可能状态,这样比用每个状态来检测所有输入是否都可行要方便些(改变了循环的内外顺序,但是不影响结果)。注意可以有不均匀进制来表示状态(进制推广:三位数 1ab, 其中a位的进制基数为A,b位的进制基数为B,则我们可以根据计数乘法原理推得,1ab = 1*(A*B)+a*(B) + b*1.)
  • Don't Get Rooked(1315,):是一个回溯问题, 主要是注意采取一个定序(从左往右然后再从上往下)的策略来枚举当前可能存在的放置点。回溯采用子问题方式,减少了全局依赖。
  • The Settlers of Catan(2258,): 简单回溯
  • Mapping the Swaps(,331):简单回溯
  • Transportation(1040,) : 仍然是简单的回溯,注意DFS函数的意义,每次要定义好DFS的意义,一般使用子问题定义较好。注意叶节点返回0 还是 cur。
  • 23 out of 5(,10344): 简单DFS和全排列生成的累加,直接把二者结合起来即可。
  • How Big Is It?(,10012): 这题折腾了半天 ,主要是有一个几何陷阱,2.0 0.2 2.0这个样例的答案是 8.0, 这个解决后,没有注意边界的特殊性,后来发现2.0 2.0 0.2的样例再检查一遍,终于PASS,结果一着急还给提交到别的题上去了,直接贡献WA。受不了,浮点数调试起来真是麻烦。DFS使用了全局版本,且无参数,感觉很不好。
  • The Sultan's Successors(,167):就是八皇后问题,不过棋牌带了权重,要求求出在92个可行解中使皇后所在位置权重和最大的解.开始直接进行最大值回溯,使用局部方法,结果WA,原因是因为权重的关系,得到的最大权值和有可能只在棋牌上放置了少于8个皇后,所以改用全局解法,在第八层跟新最大值AC。
  • Getting in Line(, 216): 同上,一遍过。
  • Garden of Eden(,10001): 题意就有点晕,就一个生命游戏的状态机上来整个物理理论吓人, 之后需要看懂他的状态转移表格的编码。回溯的策略有两种,一种是遍历所有状态,然后尝试生成目标态,这种不太好,另一种是同样冒着32层递归的风险从目标态尝试反推一个祖先。第二种方法我现在仍然没想到好的剪枝策略,不过UVA数据太弱,不剪枝也能AC了。
  • Bandwidth(, 140) : 注意有两处剪枝(两处剪枝是常用技巧,参见书上讲解), 该题输入很烦人,让我TLE了N次,呕吐,本题也需要打印方案,方法同下题。
  • Graph Coloring(1419,): 回溯,由于需要打印最优解方案,所以不得以使用全局方式对最优解进行保存,由于使用的是只有当前可行才向更深递归的方法,所以回溯函数不一定能达到第N层。所以全局解的跟新要和局部解一起,并且函数需要存储当前累计值。 PKU的数据据说太弱了,完全没有使用剪枝仍然AC了。
  • Firetruck(,208): 直接使用回溯会TLE,在回溯函数中直接剪枝一直WA, 原因是用一个vis检测就使得防止环路和判断是否可达就融合再一起了,这样要求当前节点必须在不使得当前路径形成环路的情况下还能抵达目的地,否则将其设为不可达节点,这显然误判了很多可达结点。使用floyd函数预处理后,再剪枝AC。
  • No Tipping(, 10123): 最大是22层,显然如果不剪枝肯定TLE, 感觉是个典型的DP,我用集合DP存了中间结果,DFS最后 2.6s AC。不知道如何用DP再加速。据说有个DP状态压缩,不知道是啥。由于题目只要求找到一个可行解,所以在最深层找到可行解后,不在需要执行回溯重置操作。(可参见代码)
  • Knights in FEN(,10422): 算是很经典但基础的搜索题目,由于只有10层,DFS可以,IDA可以,BFS当然更可以。 使用反向BFS+HASH 的预计算方式, 贡献六次WA后,终于AC. BUG主要集中在 将0即当成0次,又当成特殊值,结构体为初始化的部分不确定值,不能用memcpy比较, 输入有空格(第一行第一列)不能用scanf吃空格的方式, 11次跳出错误,应该在出现10次节点时终止扩展节点。
  • The most distant state(,10085): 八数码问题的小变种,思路是一直BFS下去,指导结束,取队尾元素输出即可。当然考虑到对称性,可以预计算出9种情况,直接输出可得0MS方案。 在HASH列表时又忘了将第一个元素标号设为0,导致插入时BUG。标号应该从1开始。
  • The New Villa(,321):题目看着玄乎,有人写的题解也很玄乎。其实状态只有10×1024个,直接用标准BFS即可。
  • Colour Hash(,704): 使用了双向BFS,题目要注意的是后三位没用,移动一次是移动两格。使用双向BFS要注意 当正向搜索进入反向预计算范围后,要遍历完当前层节点以便找到有反向节点与其配对且二者层数和最小的节点。另外,每次使用HASH时要初始化表(表头置零即可),否则上次样例的运算结果会对当前造成影响。
  • Children's Game(,10905):思路就是排序,不过由于字符串可能互为前缀很麻烦, 技巧是 如果 A+B> B+A 则 A > B;
  • Foreign Exchange(,10763):使用桶排序计数即可。
  • File Fragmentation(,10132):又一个题意不好懂的,使用回溯或者粗精度枚举所有可行解然后每个单独测试是否确实可行。
  • Lining Up(1118,): 直接暴力求解,求出所有斜率,存入数组中,然后排序,最后统计。没想到double用==比较尽然没有精度误差
  • Solve It(,10341):使用二分法的数值计算问题。
  • A mid-summer night's dream.(,10057):题目意思不容易搞清楚,其实就是排序,求出位于中间的那个元素即满足题意。
  • Number Sequence(1019,): 很容易想错,数字位数高了后一个数字要占好几位,基本思想就是迭代找下标,有一些有用的trick.
  • Closest Sums(,10487):暴力解决,排序好了后用 lower_bound和upper_bound。
  • All in All(1936,): 大水题,直接扫描一遍即可。
  • Camel trading(,10700):贪心,先加再乘得最大,先乘再加得最小。 注意使用strtok处理分词。
  • Shoemaker's Problem(,10026):简单的贪心, 罚金和天数二者相除即可得到权重。
  • Packets(1017,): 没有什么技巧,分类讨论即可,比较繁琐,因此需要一些trick。
  • Ants(1852,):有个思维转折,把蚂蚁相遇想象成两只蚂蚁互相穿越对方即可。
  • Minimal coverage(2620,):区间覆盖问题, 使用贪心。
  • Add All(,10954):就是一个huffman编码,注意使用两个队列,扫描一遍通过。
  • Copying Books:(1505,): 最大最小值问题,使用贪心加二分查找,由于打印等问题,编写需要一些trick。
  • Editor Nottoobad(,10602): 贪心,首先根据贪心法排序即可得到输出的顺序,然后再逐个计算需要打的字数。
  • Wine Trading in Gergovia(2940,): 一看就知道是贪心,不过开始只想到了O(n^2)的算法, 直接TLE, 直觉肯定有线性的方法, 关注于最终状态结果,得到线性算法。
  • Maximum Sum(,108): 二维的最大连续和, 固定一维,转换成一维问题,最终效率是O(n^3),  注意该题test case不是一组,题目没说明,很恶心。