contest tips and tricks
TRANSCRIPT
Contest Tips and Tricks
Maxim BuzdalovSPbSU ITMO
Zurich ETH Trainings2010-03-20
Part 1: General Questions
● Coding Conventions● Write Similar Things Similarly● Learn Code Snippets by Heart and Fingers● Writing Code on Paper● Use of Standard Library● Use of IDE
Coding Conventions
● Use the same coding conventions in your team
● If the code is formatted according to your conventions, you read it faster and understand it better
● Example: Java Coding Conventions● Feel free to slightly modify the conventions, if
the change makes code more clear
Write Similar Things Similarly
● Some algorithms contain similar code several times
● There may be (and so, will be) mistakes, or «copy-paste bugs»
● Need to develop a style which helps to avoid making such mistakes
Write Similar Things Similarly
boolean intersect(Point src1, Point trg1, Point src2, Point trg2) { if (max(src1.x, trg1.x) < min(src2.x, trg2.x) || max(src1.y, trg1.y) < min(src2.y, trg2.y) || max(src2.x, trg2.x) < min(src1.x, trg1.x) || max(src2.y, trg2.y) < min(src1.y, trg1.y) ) { return false; } int vmul00 = src2.sub(src1).vmul(trg1.sub(src1)); int vmul01 = src2.sub(src1).vmul(trg2.sub(src1)); int vmul10 = trg2.sub(trg1).vmul(src1.sub(trg1)); int vmul11 = trg2.sub(trg1).vmul(src2.sub(trg1));
return signum(vmul00) * signum(vmul01) <= 0 && signum(vmul10) * signum(vmul11) <= 0;}
Learn Code Snippets by Heart and Fingers
● Lots of solutions contain well-known and widely-used algorithms and data structures
● Some of them take too much time to remember and implement properly
– Segment intersection– Dijkstra algorithm with heap– Segment tree & Fenwick tree– Extended GCD (Integer equation solving)– Self-balancing binary trees– …– Delaunay triangulation
Learn Code Snippets by Heart and Fingers
● The solution is to:– Carefully study the algorithm/DS, both idea and
implementation– Make your fingers write the code independently of
your mind
● This helps to:– Stop wasting time in recalling the details– Think more globally while creating code
Writing Code on Paper
● Situation:– You come up with an idea of an algorithm– You have written out the calculations– The computer is busy– What to do?
● Problem:– Some of the ideas may be forgotten– The solution may contain inaccuracies, be
inefficient or simply wrong– In either case, lots of time is wasted while coding
Writing Code on Paper
● Solution:– Start writing code on paper, exactly as it will be on
the computer– Some insignificant parts (e.g. evident #include
directives, or parts of template) may be omitted● Why?– Lots of work do not consume computer time– Coding on paper has the effect similar with
discussion with a team-mate– Coding on computer will be faster as it turns to
copying the code from paper
Use of Standard Library
● Make sure you know your coding language and your standard library really good
● Avoid coding things from scratch if you have them ready in the library
● This makes your code more efficient (often) and containing less mistakes (always)
● Will you find a bug in a piece of code on the next slide? I found it after my team-mates spent two hours debugging their solution. (SPb IFMO 4, NEERC Northern QF, 2006)
Use of Standard Library for (int i = 0; i < n; ++i) { for (int j = 1; j < n; ++j) { if (a[i — 1] > a[i]) { int tmp = a[i]; a[i] = a[i — 1]; a[i — 1] = tmp; tmp = b[i]; b[i] = b[i — 1]; b[i] = tmp; } } }
Use of IDE
● Code completion. Greatly speeds up coding if used appropriately.
● Error highlighting and background compilation. Can save time, especially at the end of the contest.
● Static and dynamic analysis. Helps to find logical bugs in the code when typing.
Use of IDE
● Refactoring. Provides you with much more power than search-and-replace, useful when developing big solutions for «technical» problems.
● Code intentions. IDE shows pieces of code that can be simplified, shortened or replaced with use of standard library, and does the proposed change in one action.
Example: Static & Dynamic Analysis
Queue<Integer> qx = new ArrayDeque<Integer>();Queue<Integer> qy = new ArrayDeque<Integer>();qx.add(0);qy.add(0);while (!qx.isEmpty()) { int x = qx.remove(); int y = qx.remove(); //the bug is here for (int d = 0; d < 4; ++d) { int nx = x + dx[d]; int ny = y + dy[d]; if (!used[nx][ny] && !field[nx][ny]) { qx.add(nx); qy.add(ny); used[nx][ny] = true; } }}The declaration of qy is hinted: «The contents of a collection are updated but never queried»
Part 2: Special Questions
● Overflow and underflow● Issues with Graphs● Geometry Problems
Overflow and Underflow
● You must carefully check types you use for integer variables for overflow
● Estimate the bounds of values you store in a variable (e.g., the answer for a problem)
● Constructions like:int a = <...>int b = <...>long long c = a * b;
do not do what you want!● Things like “Wrong Answer, test 47” often
happen because of the overflow
Overflow and Underflow
● A special case of the overflow problem – loss of precision in floating-point numbers
● Precision loss of arithmetic operations (for positive values):
– addition – small loss;– multiplication – small loss;– division – small loss;– subtraction – large loss.
● double stores about 14-15 decimal digits.● long double stores about than 18 digits.● Trigonometry operations cause huge
precision loss. For different operations, the loss is different. Use appropriate ones.
● Small precision being required sometimes means we should use numerical algorithms
● Precision of 1e-3 is not always small – look at the absolute value (e.g. 1e9 → 12 digits)
Overflow and Underflow
Issues with Graphs
● Always check the statement to answer the following questions and the solution for proper support:
– Is the graph connected?– Is the graph unidirectional or bidirectional?
(Compare: “unidirectional” and “undirected”)– Can it contain cycles?– Are loops allowed?– Are duplicate edges allowed?
● It is helpful to determine possible graph types (e.g. a tree, a bipartite graph, a strongly connected graph, etc)
Geometry Problems
● The “constant multiple” for geometry algorithms is often quite large. Be accurate!
● “class point” is good. Always code this way.● Compare doubles with “epsilon”– Make epsilon a global constant– Write “less”, “equal”, “signum” functions and so on– Use these functions instead of “<”, “>”, “==”
Geometry Problems
● Estimate magnitude of values being compared
– What's the difference between the following pieces of code:
double vmul00 = (a – b) ^ (c – d);double vmul01 = (a – b) ^ (c – e);
return less_eq(vmul00 * vmul01, 0);and
return signum(vmul00) * signum(vmul01) <= 0;?
Geometry Problems
● Sometimes it is better to code geometry in integers
● When coding that way, sometimes you will have to either:
– using 64-bit integers or even arbitrary-precision arithmetic;
– modify the formula to decrease the needed number of digits.
● The problem of floating-point precision is converted to a problem of integer oveflow
Thank you!
Any questions?