Contest Tips and Tricks
Maxim Buzdalov
SPbSU ITMO
Zurich ETH Trainings
2010-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?

Contest Tips and Tricks

  • 1.
    Contest Tips andTricks Maxim Buzdalov SPbSU ITMO Zurich ETH Trainings 2010-03-20
  • 2.
    Part 1: GeneralQuestions ● Coding Conventions ● Write Similar Things Similarly ● Learn Code Snippets by Heart and Fingers ● Writing Code on Paper ● Use of Standard Library ● Use of IDE
  • 3.
    Coding Conventions ● Usethe 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
  • 4.
    Write Similar ThingsSimilarly ● 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
  • 5.
    Write Similar ThingsSimilarly 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; }
  • 6.
    Learn Code Snippetsby 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
  • 7.
    Learn Code Snippetsby 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
  • 8.
    Writing Code onPaper ● 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
  • 9.
    Writing Code onPaper ● 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
  • 10.
    Use of StandardLibrary ● 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)
  • 11.
    Use of StandardLibrary 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; } } }
  • 12.
    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.
  • 13.
    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.
  • 14.
    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»
  • 15.
    Part 2: SpecialQuestions ● Overflow and underflow ● Issues with Graphs ● Geometry Problems
  • 16.
    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
  • 17.
    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.
  • 18.
    ● double storesabout 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
  • 19.
    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)
  • 20.
    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 “<”, “>”, “==”
  • 21.
    Geometry Problems ● Estimatemagnitude 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; ?
  • 22.
    Geometry Problems ● Sometimesit 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
  • 23.