0% found this document useful (0 votes)
67 views

Helping Hand

The document provides tips for competitive programming beginners in C++. It recommends using C++ instead of C, including standard libraries, and using data types like vector and map. It warns that algorithms with complexity higher than O(n log n) may timeout, and advises learning algorithm analysis. Tips include using long long int to avoid overflow, sorting arrays before processing, and handling test cases and corner cases carefully.

Uploaded by

Ovi Poddar Antor
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views

Helping Hand

The document provides tips for competitive programming beginners in C++. It recommends using C++ instead of C, including standard libraries, and using data types like vector and map. It warns that algorithms with complexity higher than O(n log n) may timeout, and advises learning algorithm analysis. Tips include using long long int to avoid overflow, sorting arrays before processing, and handling test cases and corner cases carefully.

Uploaded by

Ovi Poddar Antor
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Helping Hand

Sabbir, Mehedi
October 15, 2018

1 Intro
If you’re new to competitive programming, this part is for you.

1. It is highly suggested that you use C++ instead of C. Just save the
file as .cpp and use all the C stuff, it doesn’t matter. Make sure your
compiler is set up for C++ 11 or C++ 14.

2. Put these lines at the top


#include <bits/stdc++.h>
using namespace std;
This will let you use the standard library functions like sort and various
data structures like vector, map etc.

3. If you’re code is too slow, you get TLE. So you should have some
idea about algorithm complexity and big O notation. something like
O(n2 log n) means that the code runs approximately k ∗ n2 log2 n (k
some small constant) instructions for input parameter of n. If this
value exceeds 108 , you will get a TLE. For example, in the above ex-
ample input size of 1000 is okay, but 10000 is not.
Even if you’re not into competitive programming, learn about algo-
rithm complexities. You will need it in your future courses.

4. The standard int holds 32 bit values (≈ ±2 · 109 ). There’s a bigger type
called “long long int” (specifier %lld) which holds 64 bits (≈ ±4 · 1018 ).
While this type isn’t always necessary, always be careful about overflow,
specifically while multiplying.

1
5. Don’t write sort function yourself. Just use STL’s sort() function. It
is the fastest comparison based function (a mixture of quicksort and
mergesort).

6. Don’t use float. It’s too inaccurate. Use double. And remember, you
can’t test equality of double using just ==. Instead check if absolute
value of difference is very small (10−8 is standard)

7. If your using, cin and cout. Just be careful that they’re slow. You can
write the following at the beginning of the main function to make them
fast.(but then output won’t be shown until all inputs are taken)
ios base::sync with stdio(false);cin.tie(NULL);

8. In problems with lots of test cases, you don’t have to take all the
inputs and then give the outputs. Rather, you can scan one input,
print output for that and repeat. Also, some judges are too strict
about extra spaces and capitalizations in output. So remember that if
you get a unexplainable WA.
Also remember to clear variables after one test case is processed. So
that later test cases give correct outputs

9. One last thing, if you get a WA and you’re sure your code is correct, you
must be mishandling corner case. These are inputs that are exceptional.
Maybe too small or too degenerate. So search for those.

2 Problem Hints
The hints are presented in 3 levels. So that if you get stuck you can read
them as necessary. For example if you’re stuck on problem 12 then look at
12th hint from 1st section. If you’re still stuck look at 12th hint from 2nd
section. And if you’re still stuck look at 12th hint from 3rd section.

2.1 Hints 1

1. It is easier to check if a string is palindrome or not than an integer.

2. The constraints are such that, you can easily brute-force it (check ev-
erything). Run a loop from 1 to n and check each number, whether it

2
is an almost prime via another loop. Be careful about the number 1
itself.

3. The description of the problem may make it seem way too tough. All
you have to do is keep track of the direction the wire is currently point-
ing at.
Initially, the wire is pointing at +x. After each bend, the orienatation
may or may not change, depending on the current direction it is point-
ing and the current bend.
Using stl string instead of char array might help.

4. Do not use recursion. Because the same function will be called again
and again. A single call to f n(10) will call f n(9), f n(8)...f n(4). f n(9)
will again call f n(8)...f n(3).
To avoid calling the same function again and again, the value of f n(i)
should be stored somewhere. It can be done with a single linear loop.

5. The first thing that comes to mind is to go greedy, try to put as many
boxes together as possible. So If I gave you 3 1 9 4 1 4 2 5 1, How
would you go greedy? Pick the largest box 9, then 5, then 4, then 3,
then 2, then 1. Basically create an ascending chain. This hints that
sorting might be useful. Use STL sort. (lookup how to use it)

6. First note that it is better to sort the array(as this way close elements
get closer in the array). Think about how that helps in making any
decision.

7. Finding the sum of all possible pairwise multiples in a range is a very


costly thing to do (specifically O(n2 ), for range size n). Instead let’s
do some algebra:
(a + b)2 = (a2 + b2 ) + 2ab
(a + b + c)2 = (a2 + b2 + c2 ) + 2(ab + ac + bc)
(a + b + c + d)2 = (a2 + b2 + c2 + d2 ) + 2(ab + ac + ad + bc + bd + cd)
···
So can you now think of an easier thing to do in a range other than
sum of all pairwise products?

8. Use map<string, int>. google “STL map”. This data structure lets
you map key variables to value variables and quickly check the values
from keys(int O(log n) time). Also use STL string instead of char array.

3
9. Just look at the sample input. Isn’t your job basically saying where
a number falls in the range 2-9-12-16-25? These values can easily be
computed as you scan the input. Then for each query, output the index
of the entry that is immediately bigger (or equal) to the input.

10. Thinking about trapeziums in the middle of the triangle is a little hard.
Instead think like this, you need to make (n − 1) cuts, So that ith cut
from the top leaves ni part area of whole triangle above it.

11. First consider those set of cells that share the same row, i.e. they are
in the same row. Then consider those that share the same column in a
similar manner.

12. You are supposed to solve it in O(n) time (n the size of grid). Save the
cell positions as a structure point or use STL pair. Start at where the
prince is, from there go to the adjacent cells if possible and from those
cells, repeat.
Handle the cases of being at the edge or corner (don’t try to access
beyond the grid). You could also put a redundant water cell along the
outside border to handle them (like the next problem).

13. Solve the previous problem first.


First realize that, each girl will go to their home fastest way possible and
the girl to make it last in x steps will produce the answer x. So you need
to find the shortest distance of all 3 girls and then output maximum
of that. Like the previous problem shortest distance is generated in
a manner of spreading from a starting position. However DFS won’t
work as DFS might reach a close point via a long route.

14. First try to solve an easier version. what if you are given just two
circles and told to compute their total area. How would you do that?
add the area of two circles and subtract their common part (since that
is counted twice). Hmm, this common part is a little tricky though.
maybe you should write a separate function for that. Now think about
this problem.
Note the common part function is a little tricky. Specifically when one
circle is completely inside another, or they do not intersect at all.

15. String and Dynamic programming. Try to think of a recursive solution


first.

4
Let “abcddda” the given string. Notice that the first and last character
of this string is the same. So the answer for “abcddda” and “bcddd” will
be the same. What will happen if the first and last char are different?

2.2 Hints 2

1. Take a string as input instead of integer. Then just a linear scan.

2. To check whether a number is almost prime, run a loop from 2 to itself.


and keep a counter of primes that divide it. (note: 1 should be handled
differently)

3. The wire may point to any of ±x, ±y, ±z axes. for every six of these
orientations, calculate by hand which direction it will point if bended
at any of ±x, ±y, ±z.

4. Let us use dynamic programming (very basic). dp[i] store the value of
f n(i). Then the value of dp[j] depends on dp[j − 1], dp[j − 2]...dp[j − 6].

5. Take the first hint’s example, sorting it gives 1 1 1 2 3 4 4 5 9. Going


greedy first takes away 1 2 3 4 5 9. So we have 1 1 4. Going greedy
again takes away 1 4. We have left 1, which can be used one last time,
i.e. ans is 3. But why was it 3? after every greedy attempt, every
distinct number was disappearing one by one. 1 stayed as it was there
most times (3). So could the answer be the maximum times an element
appears? Why can’t the answer be any less?

6. Let the smallest value that appears in the array be x. To what value
should you increase/decrease this x to obtain the optimal result?

7. Easier task: for a range [l, r] find sum of the elements, square it, then
subtract sum of squares of elements of that range.
Now that is still costly to sum elements in a range (specifically O(n)
for a range of size n). So think easier, what if l was always 0? Could
you do get those values fast? and if you can get those values fast, could
you then get values of range [l, r], quickly?
note that sum(l, r) = sum(0, r) − sum(0, l − 1) when l 6= 0.(for normal
sum and sum of squares)

5
8. let “map<string, int> mp” denote how many times a name has been
appeared, i.e mp[“abcd”] will denote how many times “abcd” has ap-
peared. So first time you get “abcd” you will have to set mp[“abcd”]
= 1, and update it thereafter.
Note, by default, mp[“abcd”] reads 0 if you never set it before.(useful)

9. If you start a loop search the numbers that will be costly as you have
lots of queries. But the values have a special property. They are sorted
in ascending order. So instead of linear search, you can divide and
conquer.

10. Making a cut, leaves a smaller triangle at the top (ignoring all other
cuts) which is similar to the original triangle. And we know that ratio
of areas of two similar shapes is the square of the ratio of any similar
dimension (like height).
So ith cut should be at a height in a specific ratio with the whole height.

11. Consider any row r from the grid. Let the no of white cells in this row
be w. So the no of black cells must be m-w. Now among these w white
cells, how many non-empty sets can be formed? 2w − 1. Calculate the
same for black cells for this row. Repeat this procedure for every row
and every column. Use long long int to avoid overflow.

12. Since you cannot go to adjacent cells at once, you have to pick any one
cell and continue along the way as long as possible. After hitting dead
end come back to a point from where you can go to another direction
and repeat. The easiest way to do this is via recursion. Once you come
back to starting position with no more place left to go, scan the whole
grid and count how many cells you touched.
Note that if you are not smart about it the recursion will be very costly.

13. While traversing the grid you need to make sure you get to closer cells
first. This is done via BFS. You can google it, but I’ll try my best to
explain it.
You will keep a “queue” (STL has one, just lookup how to use it). From
the starting position S. you will insert it’s adjacent cells into the queue
(as the structure or the pair) then you will visit the cell that is at the
top of the queue (first inserted) and go to that cell and repeat. This
way while each cell that is reachable gets into the queue, to be visited

6
sometime, you always visit a from the top of the queue and delete. so
you go to the cells as soon as possible.
Also use a visited flag. perform the bfs from all 3 girls and take maxi-
mum distance to home.

14. Finding the common part for general case is easy. Subtract triangle
from circle sector for moon shaped segment area. Add two of those.
Here is the formula for angle created by common area at center of first
r12 +d2 −r22

circle θ1 = 2 ∗ arccos 2r1 d
,here d is the distance of centers. The
formula comes from cosine law from HSC.
Now how is this going to help in current problem? Remember set theory
and venn diagrams? How areas were added and subtracted depending
on whether any area was counted more or less? Use that. Think of the
problem as 4 circles of radius r1 , r2 , s1 , s2 and use the common function,
adding and subtracting.

15. Let the string under consideration be “abcddda”.


i . . . . . j
0 1 2 3 4 5 6
a b c d d d a
Since str[i]==str[j], that means no insertion of char are needed at either
i or j. We can ”remove” both the ’a’s from our consideration. Increase
i and decrease j by 1.
i . . . j
1 2 3 4 5
b c d d d
now for the substring str[i..j] which is “bcddd”, str[i]!=str[j]. We have
to insert one char. We can insert ’d’ before 1, thus the ’d’ at j and the
inserted ’d’ will match.
. i . . . j
1 2 3 4 5
d b c d d d
Since the ’d’s are matched, we can remove it from our consideration.
Decrease j by 1. Notice that the ’b’ at i has not yet been matched, so
we cannot removeit yet from consideration.
i . . j
1 2 3 4
b c d d

7
The recursive transition we did here thus was, f (i, j −1)+1 from f (i, j).
The +1 is due to the fact that we had to insert an extra character. A
similar transition could have been made if we had inserted ’b’ after
index 5, which would be f (i + 1, j) + 1 from f (i, j).

2.3 Hints 3

1. Just check whether S[i] and S[n-1-i] are always same for the string.

2. Suppose you are checking whether 12 is an almost prime. During your


loop your code will find that 2 and 3 divides 12 and counter will be 2.
But 4, 6 etc also divide 12. To handle those, when you find a prime
divisor of x, divide x completely by that number. Thus when you learn
2 divides 12, you divide it down to 6 and then to 3 before going to the
next iteration of the loop. The rest is implementation.

3. If the wire is now pointing towards +y, then the following will occur
Bend — Now pointing at
+y — −x
−y — +x
+z — +y
−z — +y
Make such a list for all combination of movement and then simply check
with if-else conditions to determine the current position of the wire.

4. for i = 6 to n

dp[i] = dp[i − 1] + dp[i − 2] + dp[i − 3] + dp[i − 4] + dp[i − 5] + dp[i − 6]

Remember to use mod after every 2 additions or overflow might happen.

5. The answer can’t be less than the maximum frequency. If a number x


appears m times, the maximum. Then no visible box can contain two
of x’s. So we cannot go lower than m. So the answer is the maximum
frequency.
Now to find it, sort the values. Then run a loop through it, keeping a
counter that counts how many of current entry are there. The counter
is reset to maximum when there are no more of current entry left. For
example in 1 1 1 2 3 4 4 5 9, the counter’s values are 1 2 3 — 1 — 1

8
— 1 2 — 1 — 1 (the bars are resets). Counter was maximum 3, so the
answer is 3.
Handle the cases of 1 1 1 1 2 3 and 1 2 3 3 3 3.(When first or last entry
is most frequent)

6. It is always better to turn the smallest value x to 1, since 1 is the closest


”target” for x. Similarly, turn the 2nd smallest value y to 2, the 3rd
smallest value to 3 and so on. so add up the absolute value of these
differences.
Use long long int to avoid overflow.

7. Keep two arrays for the input sequence. At index i, first array will
contain sum of all elements in range [0, i] and second array will contain
sum of all elements squared in range [0, i]. You can make these arrays
as you read the input. If the arrays are arr1[] and arr2[] and they
are built for i entries. After scanning (i + 1)th entry, x, just update
arr1[i + 1] = arr1[i] + x and arr2[i + 1] = arr2[i] + x ∗ x.
Finally handle the cases where l = 0 ans use long long int, as the values
can easily be greater than 109 .

8. Suppose the current input is “abc”. If mp[“abc”] == 0, that means


“abc” has not appeared yet. so print OK and increase mp[“abc”] by
1 (mp[“abc”]++). if “abc” appears again, then mp[“abc”] == 1, so
output the string “abc” and mp[“abc”] without any space so that the
resulting output will be “abc1”. Now increase the counter of mp[“abc”]
so that mp[“abc”] now becomes 2. So the next time “abc” appears,
the output will be “abc2”.
Note, that you don’t have to concatenate anything, just print one after
another.

9. Binary search the array for with the input. You can learn about binary
search by googling it. But C++ has built-in binary search-like func-
tions. They are lower bound and upper bound (google them). How-
ever, I will advise you to write binary search yourself, if you’ve never
done so before.
also be careful about indexing, output should be 1-indexed not 0-
indexed.

10. If the whole area is A, whole height is H, cut height is h and cut

9
2
area(above) is a then Aa = Hh 2 . For ith cut Aa = ni . Now solve.
be careful about division, integer division is not same as double division.

11. Adding the row results and column results give you an overcount.
The sets which contain a single cell only are counted twice. Why?
Because they were counted while counting row-wise and also column-
wise. So n*m has to be deduced in the end to get the correct answer.

12. Keep a visited flag for each cell, so that while doing the recursion, if
you visit a cell once, you do not visit it ever again. at the end you just
have to count the visited cells.
Handle the water cells.
The problem basically is for a depth-first-search in a graph. Specifically
each cell is a node, and adjacent cells have edges between them and
you are performing DFS from the starting position to go to reachable
nodes.
Note: this is solvable via BFS too, but DFS is probably easier for a
beginner.

13. While performing BFS you can save the distance to a cell on the go.
When you go to a unvisited cell from some cell X, if X is at shortest
distance k then the unvisited cell is at distance k + 1. After perform-
ing the BFS, check the distance of the home and record that. Before
performing BFS again, remember to clear everything.
Handle the walls and monsters (not visitable).
It’s best if you see some code of BFS from the net.

14. First add the area of two big circles and subtract two small circles.
This just adds areas of rings. but two small areas are counted twice.
those are actually

common(r2 , s2 ) − common(r2 , s1 ) − common(r1 , s2 ) + common(r1 , s1 )

Now subtract this from the first area. And you’re done.

15.
f (i, j) = f (i + 1, j − 1) if str[i]==str[j]
f (i, j) = 1 + min(f (i, j − 1), f (i + 1, j)) else

10
Base case:
if(i==j) return 1;
if(i > j) return 0; (empty string)
Similar problem is finding the ”Longest Common Subsequence” of two
given strings.
Geeksforgeeks Link

11

You might also like