浅谈设计获胜策略

上传人:xins****2008 文档编号:42697533 上传时间:2021-11-27 格式:DOCX 页数:9 大小:22.79KB
收藏 版权申诉 举报 下载
浅谈设计获胜策略_第1页
第1页 / 共9页
浅谈设计获胜策略_第2页
第2页 / 共9页
浅谈设计获胜策略_第3页
第3页 / 共9页
资源描述:

《浅谈设计获胜策略》由会员分享,可在线阅读,更多相关《浅谈设计获胜策略(9页珍藏版)》请在装配图网上搜索。

1、设计获胜策略设计获胜策略 一个好的取胜之道是制定在竞赛中指导你行动的策略。无论是在好的情况下还是在坏的情况下,它将帮助你决定你的行动。用这种方法你可以在竞赛中将时间花费在解决编程问题上而不是试图决定下一步该干什么这有点像预先计算好你面对各种情况的反应。 心理上的准备也很重要。 竞赛中的策略 首先通读所有的题目;草拟出算法,复杂度,数量,数据结构,微妙的细节, 集体讨论所有可能的算法 然后选择最“笨”但却可行的算法。(注:请注意这一点,对参赛选手来说获奖就是唯一目的) 进行计算!(空间和时间复杂度,并且加上实际期望和最坏情况下的数量) 试图证明该算法错误(?原文是Try to break the

2、 algorithm) 使用特殊的(退化的)测试数据。 将问题排序:根据你所需付出的努力,将最“短”(从原文理解是指解决问题费时最短)的问题排在前面。(从“短”到“长”的次序为:以前做过的,容易的,不熟悉的,困难的) 编写程序解决一个问题 对每一道题而言,一次一道题 确定算法 构造特殊情况的测试数据 写出数据结构 编写并测试输入子程序(编写额外的子程序来显示数据输入的正确性) 编写并测试输出子程序 逐步细化:通过写注释来刻划程序的逻辑轮廓 一个部分一个部分地填充并调试代码 完成代码使其正常运转,并验证代码的正确性(使用一般情况的测试数据) 试图证明代码错误(?原文是Try to break t

3、he code)使用特殊情况的测试数据来验证代码正确性 逐渐优化但足够了即可,并且保存所有的版本(使用困难情况的(即运行时间长的)测试数据来计算出实际运行时间) 时间安排策略和“故障控制”方案 制定一个计划决定在各种(可预测的!)故障发生时的行动;想象你可能遇到的问题并计算出你所希望做出的反应。核心问题是:“你何时花费更多的时间在调试程序上,你何时放弃并继续做下一题?”。考虑以下问题: 你已经花费了多长时间来调试它? 你可能有什么样的BUG(BUG是指程序中的错误)? 你的算法有错吗? 你的数据结构需要改变吗? 你是否对什么地方可能会出错有一些头绪? 花费较短的时间(20分钟)在调试上比切换去

4、做其他别的事要好;但是你或许能够在45分钟内解决另一个问题(?原文是A short amount (20 mins) of debugging is better than switching to anything else; but you might be able to solve another from scratch in 45 mins.) 你何时返回到一个你先前放弃的问题? 你何时花费较多的时间优化一个程序,你何时放弃当前优化工作而切换去作其他事? 从这里考虑出去(?原文是Consider from here out)忘记先前的努力,着眼于将来:你如何才能就你目前所有的抓住下

5、一个小时。 在你上交你的答案之前列出一个校验表: 在竞赛结束前五分钟冻结代码?(?原文是Code freeze five minutes before end of contest?) 将所有的声明关闭。 将调试输出关闭。 确认输入输出文件名正确。 确认输入输出格式正确。 重新编译并再测试一次。 将文件以正确的文件名复制到正确的位置(软盘)。 提示和技巧 如果可以就用暴力法(即穷举法)解决 (注:居然将这条作为技巧,可见竞赛的目的就是获奖,为此要“不择手段”。) 键索引顺序搜索(KISS= Keyed Indexed Sequential Search):简单就是聪明!(?原文是KISS: S

6、imple is smart!) 提示:注意限制(在问题陈述中指明) 如果可以给你带来方便的话就浪费内存(假如你能侥幸逃脱处罚的话) 不要删除你额外的调试输出,将它注释起来 逐渐地优化,足够了即可 保留所有的工作版本 从编码到调试: 空白是好的(?原文是whitespace is good) 使用有意义的变量名 不要重复使用变量 逐步细化 在写代码之前先写注释 有可能的话尽量避免使用指针 避免使用麻烦的动态内存:静态地分配所有的东西。 尽量不要使用浮点数;如果你不得不使用,在所有使用的地方设置允许的误差(绝对不要测试两个浮点数相等) 对注释的注释: 不要写得太长,简洁的注解就可以了 解释复杂的

7、功能:+i; /* increase the value of i by 1*/ 这样的注释是毫无意义的。 解释代码中的技巧 将功能模块划定界限并且document (?原文是Delimit & document functional sections) 好像是写给某个了解该问题但并不了解程序代码的聪明人看的 任何你不得不考虑的东西 ?原文是Anything you looked at even once saying, "now what does that do again?" 总是注释数组的索引次序 记录你每一次竞赛的情况:成功之处、犯的错误,以及何处你可以做

8、得更好;利用这些记录来改进你的策略。 复杂度 基础和阶符号 复杂度分析的基本原理围绕着符号“大O”,例如:O(N).这意味着算法的执行速度或内存占用将会随着问题规模的增倍而增倍。一个有着O(N 2)的算法在问题的规模增倍时其运行时间将会减慢4倍(或者消耗4倍的空间)。常数时间或空间消耗的算法用O(1)表示。这个概念同时适用于时间和空间;这里我们将集中讨论时间。 一种推算一个程序的O( ) 运行时间的方法是检查它的循环。嵌套最深的(因而也是最慢的)循环支配着运行时间,同时它也是在讨论O( ) 符号时唯一考虑的循环。有一个单重循环和一个单层嵌套循环(假设每个循环每次执行N次)的程序的复杂度的阶是O

9、(N 2),尽管程序中同时有一个O(N)循环。 当然,递归也像循环一样计算,并且递归程序可以有像O(b N), O(N!), 甚至O(N N)的阶。 经验法则 在分析一个算法以计算出对于一个给定的数据集它可能要运行多长时间的时候,第一条经验法则是:现代(1999)计算机每秒可以进行10M次操作。对于一个有五秒钟时间限制的程序,大约可以处理50M次操作。真正优化的好的程序或许可以处理2倍甚至4倍于这个数目的操作。复杂的算法或许只能处理这个数目的一半。 640K确实是苛刻的内存限制。幸运的是,1999-2000赛季将是这个限制的最后一次起作用。 210 约等于10 3 如果有k重嵌套的循环,每重大

10、约循环N次,该程序的复杂度为O(N k)。 如果你的程序有l层递归,每层递归有b个递归调用,该程序复杂度为O(b l)。 当你在处理有关排列组合之类的算法时,记住N个元素的排列有N!个,N个元素的组合或N个元素组成的集合的幂集的有2 n个。 对N个元素排序的最少时间是O(NlogN)。 进行数学计算!将所有的数据加起来。(?原文是Plug in the numbers.) 例子: 一个简单的重复N次的循环复杂度为O(N): 1 sum=0 2 fori=1ton 3 sum=sum+i 一个双重嵌套循环的复杂度通常为O(N 2): #fill array a with N elements 1

11、 fori=1ton-1 2 forj=i+1ton 3 if(ai>aj) swap(ai,aj) 注意,虽然这个循环执行了N×(N+1)/2 次if语句,但他的复杂度仍然是O(N 2),因为N加倍后执行时间增加了四倍。 解决方案的范例 产生器 vs. 过滤器 产生大量可能的答案然后选择其中正确的(比如8皇后问题的解答),这样的程序叫做过滤器。那些只产生正确答案而不产生任何错误节点的叫做产生器。一般来说,过滤器较容易(较快)编程实现但是运行较慢。通过数学计算来判断一个过滤器是否足够好或者是否你需要尝试制作一个产生器。 预先计算 有时生成表格或其他数据结构以便快速查找结果是很有

12、用的。这种方法叫做预先计算(在这里用空间换取时间)。你可以将需要预先计算的数据和程序一起编译,在程序开始时计算;也可以干脆记住预先计算出的结果。比如说,一个程序需要将大写字母转化为小写字母,可以不需任何条件地利用一个表格进行快速查找来实现。竞赛题经常要用到素数生成一长串素数在程序中某处使用通常是很实用的。 分解(编程竞赛中最困难的事) 虽然在竞赛中经常使用的基本算法不超过20种,但是某些需要将两种算法结合才能解决的组合型问题却是很复杂的。尽量将问题不同部分的线索分离开来以便你可以将一个算法和一个循环或其他算法结合起来以独立地解决问题的不同部分。注意,有时你可以对你的数据的不同(独立)部分重复使

13、用相同的算法以有效地改进程序的运行时间。 对称 许多问题中存在着对称(例如,无论你按哪一个方向,一对点之间的距离通常是相同的)。对称可以是2路的(?原文是2-way),4路的,8路的或是更多的。尽量利用对称以减少运行时间。 例如,对于4路对称,你只需解决问题的四分之一,就可以写下4个结果,这四个结果和你所解决的一个结果是对称的(注意自对称的解答,他当然只应该被输出一次或两次)。 正向 vs. 逆向 令人惊讶地,许多竞赛题用逆向法解决比正面突破要好得多。以逆序处理数据或构造一种基于某种非明显的方式或顺序检索数据的突破策略时,要特别小心。 简化 某些问题可以被改述为一个有点不同的其他问题,这样你解

14、决了新问题,就已经有了原始问题的答案或者容易找出原始问题的答案;当然,你只需解决两者之中较容易的那个。另外,像归纳法一样,你可以对一个较小的问题的解答作一些小小的改变以得到原问题的完整答案。 Receipted from Translated by Starfish 原文: Crafting Winning Solutions A good way to get a competitive edge is to write down a game plan for what you're going to do in a contest round. This will help yo

15、u script out your actions, in terms of what to do both when things go right and when things go wrong. This way you can spend your thinking time in the round figuring out programming problems and not trying to figure out what the heck you should do next. it's sort of like precomputing your reacti

16、ons to most situations. Mental preparation is also important. Game Plan For A Contest Round Read through ALL the problems FIRST; sketch notes with algorithm, complexity, the numbers, data structs, tricky details, . Brainstorm many possible algorithms - then pick the stupidest that works! DO THE MATH

17、! (space & time complexity, and plug in actual expected and worst case numbers) Try to break the algorithm - use special (degenerate?) test cases Order the problems: shortest job first, in terms of your effort (shortest to longest: done it before, easy, unfamiliar, hard) Coding a problem - For e

18、ach, one at a time: Finalize algorithm Create test data for tricky cases Write data structures Code the input routine and test it (write extra output routines to show data?) Code the output routine and test it Stepwise refinement: write comments outlining the program logic Fill in code and debug one

19、 section at a time Get it working & verify correctness (use trivial test cases) Try to break the code - use special cases for code correctness Optimize progressively - only as much as needed, and keep all versions (use hard test cases to figure out actual runtime) Time management strategy and &q

20、uot;damage control" scenarios Have a plan for what to do when various (foreseeable!) things go wrong; imagine problems you might have and figure out how you want to react. The central question is: "When do you spend more time debugging a program, and when do you cut your losses and move on

21、?". Consider these issues: How long have you spent debugging it already? What type of bug do you seem to have? Is your algorithm wrong? Do you data structures need to be changed? Do you have any clue about what's going wrong? A short amount (20 mins) of debugging is better than switching to

22、 anything else; but you might be able to solve another from scratch in 45 mins. When do you go back to a problem you've abandoned previously? When do you spend more time optimizing a program, and when do you switch? Consider from here out - forget prior effort, focus on the future: how can you g

23、et the most points in the next hour with what you have? Have a checklist to use before turning in your solutions: Code freeze five minutes before end of contest? Turn asserts off. Turn off debugging output. Turn on all optimizations. Make sure input and output are to correct filenames. Make sure the

24、 input and output formats are correct. Recompile and test once more. Copy files to correct locations (floppy?) with correct names. Tips & Tricks Brute force it when you can KISS: Simple is smart! Hint: focus on limits (specified in problem statement) Waste memory when it makes your life easier (

25、if you can get away with it) Don't delete your extra debugging output, comment it out Optimize progressively, and only as much as needed Keep all working versions! Code to debug: whitespace is good, use meaningful variable names, don't reuse variables, stepwise refinement, COMMENT BEFORE COD

26、E. Avoid pointers if you can Avoid dynamic memory like the plague: statically allocate everything. Try not to use floating point; if you have to, put tolerances in everywhere (never test equality) Comments on comments: Not long prose, just brief notes Explain high-level functionality: +i; /* increas

27、e the value of i by */ is worse than useless Explain code trickery Delimit & document functional sections As if to someone intelligent who knows the problem, but not the code Anything you had to think about Anything you looked at even once saying, "now what does that do again?" Always

28、comment order of array indices Keep a log of your performance in each contest: successes, mistakes, and what you could have done better; use this to rewrite and improve your game plan! Complexity Basics and order notation The fundamental basis of complexity analysis revolves around the notion of big

29、 oh'' notation, for instance: O(N). This means that the algorithm's execution speed or memory usage will double when the problem size doubles. An algorithm of O(N 2) will run about four times slower (or use 4x more space) when the problem size doubles. Constant-time or space algorithms a

30、re denoted O(1). This concept applies to time and space both; here we will concentrate discussion on time. One deduces the O( ) run time of a program by examining its loops. The most nested (and hence slowest) loop dominates the run time and is the only one mentioned when discussing O( ) notation. A

31、 program with a single loop and a nested loop (presumably loops that execute N times each) is O(N 2), even though there is also a O(N) loop present. Of course, recursion also counts as a loop and recursive programs can have orders like O(b N), O(N!), or even O(N N). Rules of thumb When analyzing an

32、algorithm to figure out how long it might run for a given dataset, the first rule of thumb is: modern (1999) computers can deal with 10M actions per second. In a five second time limit program, about 50M actions can be handled. Really well optimized programs might be able to double or even quadruple

33、 that number. Challenging algorithms might only be able to handle half that much. 640K is a really tight memory constraint. Happily, the 1999-2000 season is the last time this constraint applies. 210 approx 10 3 If you have k nested loops running about N iterations each, the program has O(N k) compl

34、exity. If your program is recursive with b recursive calls per level and has l levels, the program O(b l) complexity. Bear in mind that there are N! permutations and 2 n subsets or combinations of N elements when dealing with those kinds of algorithms. The best times for sorting N elements are O(N l

35、og N). DO THE MATH! Plug in the numbers. Examples A single loop with N iterations is O(N): 1 sum=0 2 fori=1ton 3 sum=sum+i A double nested loop is often O(N 2): #fill array a with N elements 1 fori=1ton-1 2 forj=i+1ton 3 if(ai>aj) swap(ai,aj) Note that even though this loop executes N x (N+1) / 2

36、 iterations of the if statement, it is O(N 2) since doubling N quadruples the execution times. Solution Paradigms Generating vs. Filtering Programs that generate lots of possible answers and then choose the ones that are correct (imagine an 8-queen solver) are filters. Those that hone in exactly on

37、the correct answer without any false starts are generators. Generally, filters are easier (faster) to code and run slower. Do the math to see if a filter is good enough or if you need to try and create a generator. Precomputation Sometimes it is helpful to generate tables or other data structures th

38、at enable the fastest possible lookup of a result. This is called precomputation (in which one trades space for time). One might either compile precomputed data into a program, calculate it when the program starts, or just remember results as you compute them. A program that must translate letters f

39、rom upper to lower case when they are in upper case can do a very fast table lookup that requires no conditionals, for example. Contest problems often use prime numbers - many times it is practical to generate a long list of primes for use elsewhere in a program. Decomposition (The Hardest Thing At

40、Programming Contests) While there are fewer than 20 basic algorithms used in contest problems, the challenge of combination problems that require a combination of two algorithms for solution is daunting. Try to separate the cues from different parts of the problem so that you can combine one algorit

41、hm with a loop or with another algorithm to solve different parts of the problem independently. Note that sometimes you can use the same algorithm twice on different (independent!) parts of your data to significantly improve your running time. Symmetries Many problems have symmetries (e.g., distance

42、 between a pair of points is often the same either way you traverse the points). Symmetries can be 2-way, 4-way, 8-way, and more. Try to exploit symmetries to reduce execution time. For instance, with 4-way symmetry, you solve only one fourth of the problem and then write down the four solutions tha

43、t share symmetry with the single answer (look out for self-symmetric solutions which should only be output once or twice, of course). Forward vs. Backward Surprisingly, many contest problems work far better when solved backwards than when using a frontal attack. Be on the lookout for processing data

44、 in reverse order or building an attack that looks at the data in some order or fashion other than the obvious. Simplification Some problems can be rephrased into a somewhat different problem such that if you solve the new problem, you either already have or can easily find the solution to the original one; of course, you should solve the easier of the two only. Alternatively, like induction, for some problems one can make a small change to the solution of a slightly smaller problem to find the full answer. Receipted from 返回

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!