By MDK!
Crafting Winning Solutions
A good way to get a competitive edge is to write down a game plan for what you're re going to do in a contest round. this will help you 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 shoshould do next... it's sort of like precomputing your reactions to most situations.
A good way to get a competitive advantage is to write a game plan and write about what you should do during the game. This will regulate your behavior and know how to do it when you lose or are favorable. Similarly, you can focus on program problems rather than thinking about what to do next. This is like sorting out what you should do next.
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 implements possible algorithms-then pick the stupidest that works!
- Do the math! (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)
Game Round plan:
View all the questions and quickly mark their algorithms, complexity, data volume, data structure, and tricky details ,...
- Brainstorm many possible algorithms-then select the most stupid but usable Algorithms
- Mathematical estimate! (Time-space complexity: Calculate the worst case value)
- Try to find out where your algorithm is not feasible-use a special example (degradation? Scum? Abnormal ?)
- Manage those problems: first thought of for you (low to high-simple, unfamiliar, difficult)
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 show data ?)
- Code the output routine and test it
- Stepwise refinement: write comments outlining the program logic
- Fill in code and debugOne 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)
Write code-solve each problem for the first time
- Final Algorithm
- Write some tricky case
- Write Data Structure
- Code Input and test (write additional output to test data)
- Code output and Test
- Step-by-Step refinement: write comments to outline the Program Logic
- Write a part each time and Test
- Enable her to work & verify correctness (using some simple cases)
- Try the break code-Use your abnormal data to test the code correctness
- Step-by-Step Optimization-add tests as needed and keep all versions ...... (Use hard disk to test the actual running time)
Time management strategy and "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? ". 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 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 previusly?
- 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 get the most points in the next hour with what you have?
Time management policy and "Damage Control" plan
Is there a solution for preparing all kinds of (foreseeable) errors? Imagine the problems you may encounter and come up with how to correct them. The central question is: "When you spend more time on the debugging program, when can you reduce your wasted time and move on ?". Think about the following questions:
- How long does it take for you to debugging a program?
- Which bugs do you often make?
- Is your algorithm missing?
- Do you want to change your data structure?
- If something went wrong at that place, do you have any clue-(clue )?
- A short debugging (20 min) is better than any other method, but it may take 45 min to solve the problem from the beginning.
- When did you look back at the question you gave up?
- When do you spend more time optimizing, or when do you quit?
- Consider changing from the present-forget the previous achievements, focus on the future: How do you get more scores in the next hour to use 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.
Make a list before you change your solution.
- Did you freeze the code five minutes before the competition ends?
- Disable assert_encyclopedia
- Disable debugging output
Tips & Tricks
- Brute force it when you can
- KISS: Simple is smart!
- Hint: focus onLimits(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 in everywhere (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 coshould have done better; use this to rewrite and improve your game plan!
Tips and tips
- If it can be violent, do it!
- KISS: simple, smart
- HINT: Pay attention to restrictions (especially the description of the question)
- A waste of memory, if this can make your life very good (of course, if it can solve that unpleasant problem)
- Do not delete your debugging content and comment it out.
- Step-by-Step Optimization, only when more optimization is required.
- Keep all good code versions.
- Code debugging:
- Space is more and better
- Use meaningful variable names
- Do not reuse variables,
- Gradually refine,
- Comments before code.
- If possible, avoid pointers.
- Avoid troublesome dynamic memory allocation: static memory allocation.
- Try not to use the floating point type; if you have to use it, place the error in every place (do not perform the same test)
- Comment:
- Not long prose, just a brief description
- Description: high-level functions: ++ I;/* increase the value of I by */useless!
- What's strange about code
- Record functional areas and file areas
- These comments should be for smart people who know the problem, not the Code itself.
- Something you have to consider
- When I read the code, I asked several times: "What are you doing now ?"
- Always describe the index order of the array
By MDK!
ComplexityBasics and order notation
The fundamental basis of complexity analysis revolves around the notion of ''big 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 are 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 program with a single loop and a nested loop (presumably loops that executeNTimes 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).
Complexity
Basic knowledge and General Symbols
Time Mark O (N .... Etc).
Recursion!
Rules of thumb
- When analyzing an algorithm to figure out how long it might run for a given dataset, the first rule of thumb is: modern (2004) computers can deal with 100 M actions per second. in a five second time limit program, about 500 M actions can be handled. really well optimized programs might be able to double or even quadruple that number. challenging algorithms might only be able to handle half that much. current contests usually have a time limit of 1 second for large datasets.
- 16 MB maximum memory use
- 210 ~ Approx ~ 10 3
- If you haveKNested loops running aboutNIterations each, the program has O (N k) Complexity.
- If your program is recursiveBRecursive cballs per level and hasLLevels, the program O (B l) Complexity.
- Bear in mind that there areN!Permutations and2 nSubsets or combinationsNElements when dealing with those kinds of algorithms.
- The best times for sortingNElements are O (NLogN).
- Do the math!Plug in the numbers.
Rule of thumb:
- When we analyze how long the algorithm runs on the given test data, the first rule is: Contemporary computers can process M operations per second. Within 5 s, the program can handle about M operations. An Optimized Program can actually process double or four times the data. A challenging algorithm only needs to process half of this. Most of the current competitions have 1 s limit on processing large data volumes.
- Maximum Storage Limit of 16 MB
- 210 ~ Approx (approx )~ 10 3
- If your program has K loops, then your program has O (N k.
- If your program recursively generates B recursion every time, there is probably l layer, then the program has O (B l.
- Remember to arrangeN!-Evaluate the combination or subset of N elements2 nThe time complexity of processing these algorithms is probably the same.
- The best time complexity for processing to sort N elements is O (NLogN).
- Use mathematical calculations! Contain numbers.
Examples A single loop
NIterations 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 doubling
NQuadruples the execution times. Consider this well balanced binary tree with four levels:
An algorithm that traverses a general binary tree will have complexity O (
2 N). // These are examples of each time complexity. Solution Paradigms
Solution specifications
Generating vs. Filtering
Programs that generate lots of possible answers and then choose the ones that are correct (imagine an 8-queen solver) areFilters. Those that hone in exactly on the correct answer without any false starts areGenerators. 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.
Generate VS filter --- generate VS discard
Filters is the program that generates many possible answers and then selects the right answers (think about the eight queens question ). Generating is to strictly and correctly start without errors. In general, filters are easy (FAST) to de-code but slow to run. Using mathematics to calculate the value is not worth using generating instead of filters
Precomputation
Sometimes it is helpful to generate tables or other data structures that enable the fastest possible lookup of a result. This is calledPrecomputation(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 from 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-since times it is practical to generate a long list of primes for use elsewhere in a program.
Preprocessing)
Sometimes it is very helpful to generate a table or some other data structure to find a result. This is called preprocessing (which saves time ). You can write the data to be preprocessed into a program, call it at the beginning of the program, or remember the result you calculated. Here are two examples. One is a case-insensitive hash table, and the other is a prime number table. Not translate)
Decomposition (The Hardest Thing At 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 algorithm 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.
Decomposition
Although there are fewer than 20 basic algorithms used in the competition, the problem of relative synthesis needs to be integrated into two algorithms, which is a difficult challenge. Try to analyze the different parts of the problem separately, so that you can combine an algorithm to solve the problem with other algorithms that are relatively independent. Note that sometimes you can use an algorithm twice in different parts (Independent !) To significantly improve the running time of your program.
Replica ries
Export problems have into RIES (e.g ., distance between a pair of points is often the same either way you traverse the points ). specified Ries can be 2-way, 4-way, 8-way, and more. try to exploit into ries to reduce execution time.
For instance, with 4-way authentication ry, you solve only one fourth of the problem and then write down the four solutions that share your ry with the single answer (look out for self-defined Ric solutions which shold only be output once or twice, of course ).
Symmetry
There are many problems with symmetry (for example, the distance between a pair of points is usually the same, no matter how you traverse it ). The symmetry may be 2-way, 4-way, 8-way, or even more. Try to discover symmetry and shorten the running time.
For example, if the 4-way is symmetric, you only need to calculate the first of the 4 points of the question, and then write the 4 answers to the question using the symmetry and the answer (if you find a self-symmetric solution, it may only need to be calculated once or twice ).
Forward vs. Backward
Surprisingly, define contest problems work far better when solved backwards than when using a frontal attack. be on the lookout for processing data in reverse order or building an attack that looks at the data in some order or fashion other than the obvious.
Forward VS backward
Surprisingly, it is much easier to think about many games than just thinking about them. Tentatively solve the problem in reverse order or start with obvious or regular data.
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 shoshould 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.
Simplicity
Some problems can be rewritten into a problem with a different rate. Just as you are solving a new problem, you will quickly find a solution to the original problem. Of course, you should solve it easily ..... In addition, like induction, you can make minor changes to some questions to find the answer.
Finally, the translation is complete. Many Words are inappropriate. Sometimes we will refine the translation. Stepwise refinement, then, and make pefect!
By MDK!
Indicate the source for reprinting.