考试时的一些策略

在usaco training上看到这篇文章,感觉还不错,复制下来留着。。

Crafting Winning Solutions

A good way to get a competitive edge is to write down a game planfor what you're going to do in a contest round. This will help youscript out your actions, in terms of what to do both when things goright and when things go wrong. This way you can spend your thinkingtime in the round figuring out programming problems and not trying tofigure out what the heck you should do next... it's sort of likeprecomputing your reactions 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 stupidestthat works!
  • DO THE MATH! (space & time complexity, and plug in actualexpected and worst case numbers)
  • Try to break the algorithm - use special (degenerate?) testcases
  • Order the problems: shortest job first, in terms of your effort(shortest to longest: done it before, easy, unfamiliar, hard)

Coding a problem - For each, 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 showdata?)
  • Code the output routine and test it
  • Stepwise refinement: write comments outlining the program logic
  • Fill in code and debug one 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 allversions (use hard test cases to figure out actual runtime)
Time management strategy and "damage control" scenarios

Have a plan for what to do when various (foreseeable!) thingsgo wrong; imagine problems you might have and figure out how youwant to react. The central question is: "When do you spend moretime debugging a program, and when do you cut your losses and moveon?". 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 switchingto anything else; but you might be able to solve another fromscratch 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 thefuture: how can you get the most points in the next hour with whatyou 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.
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 (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 CODE.
  • 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 ineverywhere (never test equality)
  • Comments on comments:
    • Not long prose, just brief notes
    • Explain high-level functionality: ++i; /* increase 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 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 improveyour game plan!
Complexity
Basics and order notation

The fundamental basis of complexity analysis revolves around thenotion of ``big oh'' notation, for instance: O(N). This meansthat the algorithm's execution speed or memory usage will double whenthe problem size doubles. An algorithm of O(N 2) willrun about four times slower (or use 4x more space) when the problem sizedoubles. Constant-time or space algorithms are denoted O(1). Thisconcept applies to time and space both; here we will concentratediscussion on time.

One deduces the O() run time of a program by examining itsloops. The most nested (and hence slowest) loop dominates the runtime and is the only one mentioned when discussing O() notation.A program with a single loop and a nested loop (presumably loopsthat 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 programscan have orders like O(b N), O(N!), oreven O(N N).

Rules of thumb
  • When analyzing an algorithm to figure out how long it mightrun for a given dataset, the first rule of thumb is: modern (2004)computers can deal with 100M actions per second. In a five secondtime limit program, about 500M actions can be handled. Really welloptimized programs might be able to double or even quadruple thatnumber. Challenging algorithms might only be able to handle halfthat much. Current contests usually have a time limit of 1 secondfor large datasets.
  • 16MB maximum memory use
  • 210 ~approx~ 10 3
  • If you have k nested loops running about Niterations each, the program has O(N k) complexity.
  • If your program is recursive with b recursive calls perlevel and has l levels, the program O(b l)complexity.
  • Bear in mind that there are N! permutations and 2n subsets or combinations of N elements whendealing with those kinds of algorithms.
  • The best times for sorting N elements are O(N log N).
  • DO THE MATH! Plug in the numbers.
Examples

A single loop with N iterations is O(N):

 1  sum = 0
 2  for i = 1 to n
 3    sum = sum + i

A double nested loop is often O(N 2):

# fill array a with N elements
1 for i = 1 to n-1
2   for j = i + 1 to n
3     if (a[i] > a[j])
         swap (a[i], a[j])
Note that even though this loop executes N x (N+1) / 2iterations of the if statement, it is O(N 2) since doublingN quadruples the execution times.

Consider this well balanced binary tree with four levels:

An algorithm that traverses a general binary tree will have complexityO(2 N).

Solution Paradigms
Generating vs. Filtering

Programs that generate lots of possible answers and then choosethe ones that are correct (imagine an 8-queen solver) arefilters. Those that hone in exactly on the correct answerwithout any false starts are generators. Generally, filtersare easier (faster) to code and run slower. Do the math to see ifa filter is good enough or if you need to try and create a generator.

Precomputation

Sometimes it is helpful to generate tables or other datastructures that enable the fastest possible lookup of a result.This is called precomputation (in which one trades spacefor time). One might either compile precomputed data into a program,calculate it when the program starts, or just remember results asyou compute them. A program that must translate letters from upperto lower case when they are in upper case can do a very fast tablelookup that requires no conditionals, for example. Contest problemsoften use prime numbers - many times it is practical to generatea long list of primes for use elsewhere in a program.

Decomposition (The Hardest Thing At Programming Contests)

While there are fewer than 20 basic algorithms used in contestproblems, the challenge of combination problems that require acombination of two algorithms for solution is daunting. Try toseparate the cues from different parts of the problem so that youcan combine one algorithm with a loop or with another algorithm tosolve different parts of the problem independently. Note thatsometimes you can use the same algorithm twice on different(independent!) parts of your data to significantly improve yourrunning time.

Symmetries

Many problems have symmetries (e.g., distance between a pairof points is often the same either way you traverse the points).Symmetries can be 2-way, 4-way, 8-way, and more. Try to exploitsymmetries to reduce execution time.

For instance, with 4-way symmetry, you solve only one fourthof the problem and then write down the four solutions that sharesymmetry with the single answer (look out for self-symmetricsolutions which should only be output once or twice, of course).

Forward vs. Backward

Surprisingly, many contest problems work far better when solvedbackwards than when using a frontal attack. Be on the lookout forprocessing data in reverse order or building an attack that looksat the data in some order or fashion other than the obvious.

Simplification

Some problems can be rephrased into a somewhat different problemsuch that if you solve the new problem, you either already have orcan easily find the solution to the original one; of course, youshould solve the easier of the two only. Alternatively, likeinduction, for some problems one can make a small change to thesolution of a slightly smaller problem to find the full answer.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值