I saw in the comments of Codeforces Round #823 (Div. 2) that many C++ users needed to use setprecision
to get AC on problem B. Fortunately, as a Java user, I didn't face the issue this time, but it made me wonder: what are some "gotchas" that people who are newer to competitive programming should look out for?
I also recall that in last year's FB HackerCup, where we need to run code locally, a friend of mine who uses C++ didn't set their local stack size high enough and therefore couldn't successfully run their otherwise-correct code on the full input set.
I know for Java, I painfully learned early on that Java's sort routines on primitive arrays have worst case O(n^2) runtime using a Quickselect variant, and that very smart hackers can construct adversarial inputs that cause a Java solution to get TLE.
So, in your experience, what are some things that have tripped you up?
I usually define my adjacency list, visited array, and other things globally for graph problems and reset them at the end of every test case. So one day I had hard time debugging code for a graph problem. After debugging for hours mistake turned out to be that I wasn't resetting the global things in some cases where I was using continue.
Now I reset the global variables at the start of every test case like this.
Similar to this, I have debugged several times early return conditions while still needing to read the input. So, for future test cases, the input was just messed up.
I make a solve function and a cleanup function separately. Then in main, call solve and then cleanup.
Definitely agree with you here!
But perhaps as another gotcha, I found that sometimes using 64-bit integer types can cause timeout, especially if your program is on the edge of the runtime limit. Maybe in Java this is worse since execution is typically slower than C++ already.
Or for example 1677A - Tokitsukaze и странное неравенство which may get MLE for using 64-bit integers.
this by rotavirus
The very first contest here at codeforces, I solved one problem, then got hacked for the worst case O(N^2) sorting on primitive type in Java. That's when I learned I better use auto-boxing for sorting in Java....
In C++ custom sort function, if I forgot to use references for the 2 input parameters, it can lead to slow execution if the structs are big.
A size of a vector is an unsigned integer, therefore, this for loop :
for(int i=0; i<v.size()-1; i++)
produces a runtime error or TLE when
v
is empty because its condition isi < (0-1)
Since it is stored as an unsigned int, the condition becomesi < SOME_LARGE_NUMBERS
because in this case-1
cannot be stored in an unsigned numberThe first paragraph is funny because the answer is either $$$x$$$ or $$$x.5$$$ lol
quite surprisingly though, I found out that python has 10+ digits of precision by default during the round.
maybe python really is OP.
Not sure what your point is, but you would have to use setprecision in order to solve this problem in C++ with cout. Although there can be at most one decimal place, that is enough to require that the answer is printed as a floating-point type, which defaults to 6 significant figures without setprecision. This leads to wrong answers (on pretest 3) when the answer is very large.
It's the number of significant figures (not the number of decimal places) that's relevant here, with the .5 case ensuring that you can't simply use an integer type.
First, of course you can use integer type. If the value is odd, output .5 at the end.
Second, to solve this problem setprecision wasn't required. Probably what was further required was to think outside the conventional "well i'll just binary search cuz this derivative seems pretty monotonic to me". If you buried yourself down the setprecision hole, you were very likely going to get stuck there, and by extention WA/FST'd
If a programmer were to use an integer type and output ".5" for the case where the answer requires it, that would the suggest that the programmer is deliberately avoiding the use of floating point types. The whole point of that paragraph was about those who didn't know of any precision issues with printing floating-point types, so it wouldn't make sense for them to go out of their way to restrict their code to handling integer types only.
Regardless of which approach you use, whether it was a binary search or a simple average of the maximum and minimum effective positions or some other approach, there will be cases where the answer is not an integer, and such answers would need to be printed. Programmers who don't know about precision concerns in floating-point types would naturally print the answer as a floating-point type, which is what leads to the WA, regardless of their actual approach in solving the problem. The use of
setprecision
, or an integer type with a ".5" string printed separately if needed, would imply foreknowledge of issues with floating-point types, which is exactly what this thread is highlighting.I never claimed the uselessnes/obsolence of using setprecision, I merely parodied its use in this example-- I repeat: let's say someone would've been clever and found the (min+max)/2 solution. Even if they were to use floating point to calculate this value, they were to bump in no issues. If you were to write a "brute" solution by binarysearching the answer, you could've failed. Yet, the extensive binarysearch was unnecesarry, the minute the binary search started to add values to the answer <0.1, it was pointless: just round the value. (Edit: I don't claim any contestant should've done this or be aware of this-- I just point out that setprecision's use could've only lead you to a bad ending, whereas anything else woudl've circumvented this issue)
If they were unaware of
setprecision
, they would never be able to solve this using floating-point types. For example, compare 173925122 and 173500218setprecision
's use is necessary simply because there are cases where the answer has 7 significant figures and is not an integer. No matter what approach you use to calculate such answers, it cannot be printed using a floating-pointcout
withoutsetprecision
.The only way to circumvent the precision issue would be to avoid the use of floating-point types (like the integer followed by ".5" string) or a different way to print the answer (other than
cout
), but one who is accustomed to usingcout
(or evenprintf
without specifying precision) and lacks the foreknowledge of the limited default precision in printing floating-point types should not be expected to try these alternative approaches.Ok then, thank you. I've learned today two retarded things
As a (mostly) Python user it has to be this https://codeforces.net/blog/entry/101817
Thanks to this beethoven97 got the highest number of hacks in a contest https://codeforces.net/blog/entry/104725?f0a28=1
Actually I think of some others
getting a TLE because of using
unordered_map
instead ofmap
when calculating
1<<x
and the result exceeds the limit of integer. Should be using1ll << x
insteadpassing a vector to a function as a value like this :
void f(vector<int> v)
runs in $$$O(N)$$$ While passing it by reference like this :void f(vector<int> &v)
runs in $$$O(1)$$$ This becomes a troublesome if we run the function that passes the vector as value inside a querysorting compare function should returns false if elements are equal
resetting an array using a memset in a multiple test cases scenario might leads to TLE if the array is declared globally with a static size of maximum possible $$$N$$$
C++
map
's operator[]
always creates an element, which might cause TLs: https://codeforces.net/blog/entry/61459?#comment-454131log10()
158174611
I could have been CM by now if I made a normal count_digits function but instead, I used log10(X) which fails if X is equal to $$$10^{18}-1$$$
Last year, on Facebook Hacker Cup Round 2, I didn't think to create a new file for input. So, when I go the massive input, I tried to COPY PASTE into my tiny CLion input console. Unsurprisingly, it didn't work, given that the test data had around 7 million characters.
This year, I got my revenge (somewhat) by winning a t-shirt in round 2.
This problem
As a C# programmer, there's something to know about floating point numbers: the representation depends on the locale of the machine executing the code. For example the number 1.5 (US writing) would be 1,5 in most other parts of the world. When I was competing on yandex algorithms, there was a task that required to read in a double value (done with
double.Parse(Console.ReadLine())
). Due to yandex not using the US locale on their servers, I get a RTE verdict. Took me a while to figure out what went wrong. I never ran into this issue on any other website.I'm surprised no one said
-1%2=-1
I compiled a few of those here