一、ACM算法总结及刷题参考
(摘自:http://www.cnblogs.com/flipped/p/5005693.html)
初期:
一.基本算法:
(1)枚举. (poj1753,poj2965)
(2)贪心(poj1328,poj2109,poj2586)
(3)递归和分治法.
(4)递推.
(5)构造法.(poj3295)
(6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)
二.图算法:
(1)图的深度优先遍历和广度优先遍历.
(2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)
(3)最小生成树算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)
(4)拓扑排序 (poj1094)
(5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)
(6)最大流的增广路算法(KM算法). (poj1459,poj3436)
三.数据结构.
(1)串 (poj1035,poj3080,poj1936)
(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)
(3)简单并查集的应用.
(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)
(5)哈夫曼树(poj3253)
(6)堆
(7)trie树(静态建树、动态建树) (poj2513)
四.简单搜索
(1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)
(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)
(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)
五.动态规划
(1)背包问题. (poj1837,poj1276)
(2)型如下表的简单DP(可参考lrj的书 page149):
1.E[j]=opt{D[i]+w(i,j)} (poj3267,poj1836,poj1260,poj2533)
2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)
(poj3176,poj1080,poj1159)
3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)
六.数学
(1)组合数学:
1.加法原理和乘法原理.
2.排列组合.
3.递推关系.
(POJ3252,poj1850,poj1019,poj1942)
(2)数论.
1.素数与整除问题
2.进制位.
3.同余模运算.
(poj2635, poj3292,poj1845,poj2115)
(3)计算方法.
1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)
七.计算几何学.
(1)几何公式.
(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)
(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)
(poj1408,poj1584)
(4)凸包. (poj2187,poj1113)
中级:
一.基本算法:
(1)C++的标准模版库的应用. (poj3096,poj3007)
(2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)
二.图算法:
(1)差分约束系统的建立和求解. (poj1201,poj2983)
(2)最小费用最大流(poj2516,poj2516,poj2195)
(3)双连通分量(poj2942)
(4)强连通分支及其缩点.(poj2186)
(5)图的割边和割点(poj3352)
(6)最小割模型、网络流规约(poj3308, )
三.数据结构:
(1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)
(2)静态二叉检索树. (poj2482,poj2352)
(3)树状树组(poj1195,poj3321)
(4)RMQ. (poj3264,poj3368)
(5)并查集的高级应用. (poj1703,2492)
(6)KMP算法. (poj1961,poj2406)
四.搜索
(1)最优化剪枝和可行性剪枝
(2)搜索的技巧和优化 (poj3411,poj1724)
(3)记忆化搜索(poj3373,poj1691)
五.动态规划
(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)
(2)记录状态的动态规划. (POJ3254,poj2411,poj1185)
(3)树型动态规划(poj2057,poj1947,poj2486,poj3140)
六.数学
(1)组合数学:
1.容斥原理.
2.抽屉原理.
3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).
4.递推关系和母函数.
(2)数学.
1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)
2.概率问题. (poj3071,poj3440)
3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)
(3)计算方法.
1.0/1分数规划. (poj2976)
2.三分法求解单峰(单谷)的极值.
3.矩阵法(poj3150,poj3422,poj3070)
4.迭代逼近(poj3301)
(4)随机化算法(poj3318,poj2454)
(5)杂题.
(poj1870,poj3296,poj3286,poj1095)
七.计算几何学:
(1)坐标离散化.
(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
(3)多边形的内核(半平面交)(poj3130,poj3335)
(4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)
高级:
一.基本算法要求:
(1)代码快速写成,精简但不失风格
(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)
(2)保证正确性和高效性. poj3434
二.图算法:
(1)度限制最小生成树和第K最短路. (poj1639)
(2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)
(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446
(3)最优比率生成树. (poj2728)
(4)最小树形图(poj3164)
(5)次小生成树.
(6)无向图、有向图的最小环
三.数据结构.
(1)trie图的建立和应用. (poj2778)
(2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法
(RMQ+dfs)).(poj1330)
(3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的
目的). (poj2823)
(4)左偏树(可合并堆).
(5)后缀树(非常有用的数据结构,也是赛区考题的热点).
(poj3415,poj3294)
四.搜索
(1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)
(2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)
(3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)
五.动态规划
(1)需要用数据结构优化的动态规划.
(poj2754,poj3378,poj3017)
(2)四边形不等式理论.
(3)较难的状态DP(poj3133)
六.数学
(1)组合数学.
1.MoBius反演(poj2888,poj2154)
2.偏序关系理论.
(2)博奕论.
1.极大极小过程(poj3317,poj1085)
2.Nim问题.
七.计算几何学.
(1)半平面求交(poj3384,poj2540)
(2)可视图的建立(poj2966)
(3)点集最小圆覆盖.
(4)对踵点(poj2079)
八.综合题.
(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263)
补充:
Dp状态设计与方程总结
1.不完全状态记录
<1>青蛙过河问题
<2>利用区间dp
2.背包类问题
<1> 0-1背包,经典问题
<2>无限背包,经典问题
<3>判定性背包问题
<4>带附属关系的背包问题
<5> + -1背包问题
<6>双背包求最优值
<7>构造三角形问题
<8>带上下界限制的背包问题(012背包)
3.线性的动态规划问题
<1>积木游戏问题
<2>决斗(判定性问题)
<3>圆的最大多边形问题
<4>统计单词个数问题
<5>棋盘分割
<6>日程安排问题
<7>最小逼近问题(求出两数之比最接近某数/两数之和等于某数等等)
<8>方块消除游戏(某区间可以连续消去求最大效益)
<9>资源分配问题
<10>数字三角形问题
<11>漂亮的打印
<12>邮局问题与构造答案
<13>最高积木问题
<14>两段连续和最大
<15>2次幂和问题
<16>N个数的最大M段子段和
<17>交叉最大数问题
4.判定性问题的dp(如判定整除、判定可达性等)
<1>模K问题的dp
<2>特殊的模K问题,求最大(最小)模K的数
<3>变换数问题
5.单调性优化的动态规划
<1>1-SUM问题
<2>2-SUM问题
<3>序列划分问题(单调队列优化)
6.剖分问题(多边形剖分/石子合并/圆的剖分/乘积最大)
<1>凸多边形的三角剖分问题
<2>乘积最大问题
<3>多边形游戏(多边形边上是操作符,顶点有权值)
<4>石子合并(N^3/N^2/NLogN各种优化)
7.贪心的动态规划
<1>最优装载问题
<2>部分背包问题
<3>乘船问题
<4>贪心策略
<5>双机调度问题Johnson算法
8.状态dp
<1>牛仔射击问题(博弈类)
<2>哈密顿路径的状态dp
<3>两支点天平平衡问题
<4>一个有向图的最接近二部图
9.树型dp
<1>完美服务器问题(每个节点有3种状态)
<2>小胖守皇宫问题
<3>网络收费问题
<4>树中漫游问题
<5>树上的博弈
<6>树的最大独立集问题
<7>树的最大平衡值问题
<8>构造树的最小环
二、
ACM大赛准备(经验1)
(摘自:https://zhidao.baidu.com/question/128919957.html)
ACM常用算法及练习
第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,
因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打
出来.
1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成树(先写个prim,kruscal要用并查集,不好写)
3.大数(高精度)加减乘除
4.二分查找. (代码可在五行以内)
5.叉乘、判线段相交、然后写个凸包.
6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简)
7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式.
8. 调用系统的qsort, 技巧很多,慢慢掌握.
9. 任意进制间的转换
第二阶段:练习复杂一点,但也较常用的算法。
如:
1. 二分图匹配(匈牙利),最小路径覆盖
2. 网络流,最小费用流。
3. 线段树.
4. 并查集。
5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp
6.博弈类算法。博弈树,二进制法等。
7.最大团,最大独立集。
8.判断点在多边形内。
9. 差分约束系统.
10. 双向广度搜索、A*算法,最小耗散优先.
ACM大赛准备(经验2)
(摘自:https://blog.csdn.net/u011372705/article/details/50051743)
1. 比赛中评测会有些慢,偶尔还会碰到隔10分钟以上才返回结果的情况,这段时间不能等结果,必须开工其他题,如果WA,两道题同时做。交完每道题都要先打印。
2. 比赛时发的饭不是让你当时就吃的,那是给你赛后吃的。基本上比赛中前几名的队都没人吃,除非领先很多。
3. 很多选手,尤其是第一次参加比赛的,到一个新环境,全当旅游了,参观的参观,找同学的找同学,玩玩乐乐就把正事抛到脑后了,结果比赛自然没什么好成绩,这样的例子太多了。所以到参赛地后要时刻不忘自己是来比赛的,好好休息、备战。
4. 参赛前一天要睡10个小时以上,非常有助于保持比赛中的精力,很多时候比赛到3个多小时队员就没劲了就是这个原因。前一天晚饭与当天早饭要吃好,理由同上,要知道下顿饭得下午3点赛后才能吃。
5. 到新环境,时刻注意远离疾病,感冒肠炎病不大,却是成绩的天敌。
6. 英语不好,看不懂的,要勤查词典,懒一次就少一道题,远离奖牌。
7. 可以紧张,杜绝慌张,慌张是出题的敌人,任何时候,如果发现自己或者队友出现慌张的情况,提醒深呼吸。
8. 照着纸敲代码和sample数据时不要敲错,特别注意文字信息。
9. 第一道简单题交给队中最稳的人做,万一遇到麻烦也不要慌,如果有很多队都出了就更不必着急了,它必定是简单题,必定是可以很快做出来的,晚几分钟也比罚掉20分好。另外注意不要PE。
10. 最后一小时是出题高峰,谁松懈,谁落后。最后一小时出一道是正常,出两道更好。
11. 无论是否有人通过,所有题必须全读过,最好每道题都有两人以上读过,尽量杜绝讲题现象。要完全弄清题意,正确的判断出题目的难易,不要想当然。
12. 虽然讨论有助于出题,但是以往每赛区第一名基本都是各自为战,但是互相了解,觉得一道题适合其他人做就转手。
13. 保持头脑灵活,在正常方法不行时想想歪门邪道,比如换种不常见的特殊的数据结构,加预处理,限时搜索等。效率是第一位的,如果觉得DP麻烦就用记忆化搜索,总之考虑清楚后就要在最短时间出题。
14. 竞赛中更需要比平时稳定,程序出来后要检查重点地方,尽量1Y。对于WA的题,不要改一处就交,很可能还有错的地方,要稳,要懂得在压力下也要仔细。对WA的题测试时要完整,必须每个点都测到,但不一定特别复杂。要考虑到测试的各种边界情况,比如矩阵可能为1*1或1*n或m*1。
15. 除非做出的人很多,否则最后考虑复杂几何题,精度造成的问题太多了。对double型操作要小心判断大小、绝对值等情况。一般情况下不要用float型。
16. 块复制要小心,检查相应的部分是否已经正确修改。
17. 纸上写程序要尽量完整,每道题上机时间(包括输入、测试和调试)不要超过一小时。程序出错如果一时无法排除就应该打印出来阅读而把机器让出来。
18. 提交时注意题号,不要交错题。由于PC^2的界面,这种情况时有发生。
19. 尽可能想到题目可以用到的数学的东西。
20. 初始化必不可少。
21. 数组行列下标不要弄反,位运算或字符串哪头是0和n不要搞反。
22. 提交时记得把所有的调试信息都关掉。
23. 实在迫不得已才可换人做题。
24. 有想法后,写程序之前想好时空效率。比赛中一般不会出现时限30秒以上的题(国外赛区除外),10秒及以上的一般不会超过3道。
25. 竞赛机会每年只有一次,训练了很长时间,如果比赛中出现疏失,那么今后一年都会后悔。对于不准备明年参赛的同学,更是要珍惜最后一次参赛机会。
《组队赛说明》
1 要有做题比较多的队员,对于各种题型都有所涉及,做题稳,一般对前两道简单题能够保证快速,并且99%以上一次AC。
2 要有人专门应付数学与几何题,但复杂的几何题要放在最后做,对一些常用的函数要有模版准备。如精度控制,叉积,凸包等。
3 要有人能够对付麻烦的题,并保证一定的通过率,大多数的比赛都至少有一道这样的题,如 POJ 1913,TOJ 1092。
4 要有人对DP非常之熟,单次、双次、相对等情况都不在话下。对经典DP手到擒来。
5 要有人对稀奇古怪的算法都做过程序,涉猎广,对于数论、图论中的一些特殊结论都知道。如 TOJ 1584,ZOJ 1015,UVA 10733。
6 要有人对复杂的通用算法做过程序,如网络流中的最小费用最大流等等一系列的流,求割点/割边,启发式搜索/搏弈等。
7 模版要自己写,并且另两个人都认真读过,用以往题目进行多次的测试。模版要全,但要控制篇幅,因为很多赛区已开始限制页数。
8 要有人对 linux/vi/gcc 系统熟悉,对PC^2熟悉,一定注意正式比赛时不要出现提交错题的情况。另外也要试用Dev-C++等Windows下的免费软件。总之熟悉比赛环境。
9 每次练习赛都要当作正式比赛来做,要确保所有的题都看过,赛后要把没做出来的题尽量补上。
10 可能的话多看看以往比赛的总结、照片和录象,缩短与正式竞赛的距离,避免正式竞赛时紧张得做不出题等情况。
最好的情况就是对于各种题目三个队员都能做,但是又各有侧重。
要保证出来一道题能够有人会做、敢做,至少也要知道做法。
ACM大赛准备(经验3)
(摘自:https://blog.csdn.net/CooperNiu/article/details/78690052)
正确的开局:
-
三人分读题目,切记每开始阅读一个新的题目时一定告诉队友,作上标记,以防重复阅读,浪费资源;
-
开局并非需要一个队员负责调整 IDE,打开 PC^2,写好头文件甚至一些常用模板。
- 切记打开 BOARD,并且定期刷新,随时准备跟风。
比赛中的状态:
-
有队伍过了 X 题: 将被过掉的题目(通常很快就被 AC 的题目为水题,但也有意外情况)交由团队中发挥最为稳定的选手阅读并尝试 Coding。若遇此题已被阅读的情况,已读题目的选手深入尝试得出解题算法,如果有自信便直接开始 Coding,比赛中比较忌讳题意转述。
-
这道水题我能做:
- 稳过的题目(主体算法清晰,细节明确,有把握),那还不开写等什么呢!!?
- 可尝试题目(主体算法清晰,细节待定),基于没有其他队友使用键盘的情况下进行上机编码,若其间有队友提出自己有了稳过的题目,立即打印未完成的代码,让出键盘,在边上进行纸上编码。
- 朦胧的题目(有些许灵感,主体算法不清晰),这样叫做能做?呵呵,继续想,至少保证主体算法
- 思路明确…
- 这个题目类型应该是 XX, 我并不擅长, 应该让队友来做: 告知队友
该题目编号和你预先判定的算法方向,仍然忌讳题意转述。
After coding:
- 排除所有 compile error 和任何可以的 warning(尽可能排除 gets()函数警报等不能规避的warning 以外的所有 warning)。以文件方式写抄好 Sample Input,进行测试。接着抄写 Sample
Judging Result && Debug:
注意,评测结果返回可能会非常缓慢,其间切勿等待,继续尝试其他题目
- 返回结果:
- Yes—该干嘛干嘛去
- No
- Runtime Error 优先检查代码数组边界是否足够大,是否有除 0 或者负数开根等违例操作
- Time Limit Exceeded 优先检查是否存在死循环
- Wrong Answer
- 1.重读题意(有必要时,让队友重新读题后交流验
证题意 - 2.算法严谨性检查(有必要时,与队友进行讨论
- 3.代码严格检查,以下罗列部分常见错误
- a) 输入输出格式错误
- b) 数据类型错误(运行中数据超界)
- c) 数组变量范围过小(也会导致 WA,不一定就是 RE)
- d) 变量名输入错误,语句遗漏(如变量初始化)若反复检查仍然没有发现 Bug,可与队友交流,向队友详细讲解算法代码以察觉潜在
Bug若检查后发现 Bug:在纸上立即修复,完成后再次严格检查代码,特别留意是否存在与该 Bug 类似或相关的其他 Bug 存在,保证代码正确性后再向正在使用键盘的队友申请试用键盘,修改源码后再度进入 After Coding 阶段。
- 1.重读题意(有必要时,让队友重新读题后交流验
比赛后期(12:00-14:00):
这个时间段是新手队伍的疲软期,也是强队开始爆发拉开差距的时候
关于午餐:主办方发的午餐尽量不吃,以节约时间;容易空腹感过重的队员我推荐: 士力架,你值得拥有
在这个时候所有队员应该根据场上形势判定过题目标定位,根据自己的实力和每个题目的进度以及通过情况决定是否采取全员集火策略。最后 1h 封榜后事过题高峰期,注意留意场上气球变化,留意是否有某种颜色的气球在场上爆增的情况,控制心态,绝不言弃,就算最后几分钟想出一个题目的算法,也有可能爆发编码将其过掉冲刺阶段(最后 15min),当时的 Coder 可以根据自己的个人习惯要求队友离场以降低心理压力,可以使用题目密封信封遮盖电脑上的时间显示方便全力冲刺
Tips:
- 其他队友有题能写,如果当前 Coder 占着键盘发呆超过 3 分钟请理解滚下键盘,说明他根本没有想好那个题目。(离开键盘同时记得打印代码)
- 没事做的队员不要盯着队友编码,尽量不去注意他,不要过于频繁的追问编码进度;这些行为都会导致 Coder 的 Psycho-Pass 迅速上升;那样的话也许你就再也没有机会感谢大学同学的不杀之恩了(当然这个根据选手习惯,例如有些队员需要队友帮忙监督是否有编码错误同时这样做并不会感受到额外的压力)
- 如果遇到卡水题(全场通过队伍数高于 60%的题目,当然这个是根据你的队伍的强度来决定的)超过 1h 的情况,可以尝试请求队伍重炼(不要沿用任何你的代码)
- 非 Coding 状态队员注意定期(15-20 分钟为佳)提醒使用电脑的队员刷新 Board 以察觉潜在的高通过率的题目
- 对于编码越没信心,请纸上编码越详细
- 没有思路或者头晕的时候可以尝试去洗手间洗脸以及在赛场上站立一会儿
- 参赛前一天可以尝试睡足 10 小时,但是请放弃前一天的午休,以夜间难以入睡
- 减少代码复制粘贴,尽量携程函数方便修改
- 可以紧张,但若发现自己或队友出现紧张情况,可以提示其深呼吸以缓解时空效率危险且代码量大的程序完成优先度较低 ,没有神级计算几何选手的队伍,计算几何类型题目(非水计算几何题)完成优先级较低
- 比赛周忌讳学习新的算法
- 比赛周忌讳连续数日的高强度训练
- 比赛周推荐阅览 M67 等博客,翻阅小学奥数题目以保持思维活跃打开思路