I noticed that sometimes I do some horrible things while solving easy problems. If you struggled with the first $$$2$$$ problems from the previous round, you might also have made some huge mistakes that should not happen.
The point of this blog: I will show you my terrible ways of approaching each of these problems and you will be able to see all of the stupid things that I did. Then I will show you the proper way to approach the tasks, and then you can think which approach is more similar to yours, and maybe it will help you to improve.
Problem A. Turtle and Good Strings
My approach during contest (terrible way)
- I open the statement, incorrectly rephrase it: you are given a string, you should divide it into several substrings, so in each substring the first and the last letters are different
- I think of a dp solution, then I sloppily prove that I should take no more than $$$2$$$ substrings. I submit my non-dp solution $$$\color{red}{WA 2}$$$.
- I look at my solution for a minute or two without being able to find the issue. Then I decide to write dp $$$\color{red}{WA 2}$$$.
- After solving $$$D1$$$ and $$$D2$$$, I return to the problem and find a bug in my dp solution: I fix it and resubmit $$$\color{red}{WA 2}$$$.
- I reread the statement. This time I understand it correctly. I feel relieved, make a quick fix to the first submission $$$\color{red}{WA 2}$$$
- I scan through my code. Somehow I figure out that the condition $$$ \texttt{s[0] } != \texttt{ s[n-1]} $$$ is the only condition that matters. I make a submission and finally get an $$$\color{green}{AC}$$$.
What went wrong
It is clear as day that everything I did here was horrifying.
a)
I did not read the statement properly and was solving a different problemb)
I did not believe in the "proof" I came up with, it was just hopeful guessing with self-deception.c)
The whole thing from start to finish is very messy. I did not think clearly
I think there are $$$2$$$ main reasons why all of it happened:
1)
I was trying to be as fast as possible and was cutting corners2)
I was treating the problem as an "easy one", and was not properly solving it. I was hoping that my experience would be enough to solve the problem without putting any effort into it.
Good way to solve the problem
- I read the problem statement and correctly rephrase it: You are given string $$$S$$$. Divide it into $$$2$$$ or more substrings. If a substring starts with a letter $$$X$$$ , no substrings after it can end with this letter $$$X$$$
- I don't rush into thinking how to solve the problem. Instead, I try to understand how the statement "works". I make two simple observations: The first substring will always start with letter $$$s[0]$$$. The last substring will always end with $$$s[n-1]$$$.
- These observations help me to deduce that $$$if \texttt{ s[0] } == \texttt{ s[n-1] }$$$, the first substring will always start with the same letter as the last substring ends, so the answer will always be $$$\color{red}{NO}$$$. From this point I should only think about case $$$\texttt{ s[0] } != \texttt{ s[n-1] }$$$.
- If we take only $$$2$$$ substrings, the first one will always start with $$$s[0]$$$, and the second one will always end with $$$s[n-1]$$$. $$$\texttt{ s[0] } != \texttt{ s[n-1] }$$$
=>
no matter how we divide the string into $$$2$$$ substrings, it will always be good. - We end up with the simplest solution: we output $$$\color{green}{YES}$$$ only in case when the first and the last letters of the string are different.
Problem B. Turtle and Piggy Are Playing a Game 2
My approach during contest (terrible way)
- The first thing I think is that both players should do operations that change $$$a_1$$$
- If the $$$a_1$$$ and $$$a_2$$$ are the same, it is impossible to change $$$a_1$$$. I get stuck here for several minutes
- I look through testcases, waste some additional minutes, and skip the problem.
- I return to it and reread the statement. Immediately after rereading it, I say: Oh, I got it! If $$$n$$$ is even, the last operation is $$$max()$$$ , otherwise it is $$$min()$$$
- I start writing code: I write if(n%2 == 0). Then I get stuck. I have no idea what to do from this point.
- In both cases the last operation would be on $$$a_1, a_2$$$ elements, I know what $$$a_1$$$ is equal to, I have to figure out $$$a_2$$$
- I look at the sample and notice it is roughly equal to the median value out of all elements except $$$a_1$$$
- I notice that my solution does not work because of the $$$a_1$$$ elements. I delete that part of the solution. I submit $$$\color{red}{WA 2}$$$
- I decide to return to idea "The first element is the only one that matters". I write this greedy solution $$$\color{red}{WA 2}$$$
- I make a guess that solution with median values is closer to the truth I decided to submit it without extra things $$$\color{green}{AC}$$$.
What went wrong
I think the paragraph above is so crazy that it is pretty difficult to point out specifically what was wrong(everything). Here is my attempt:
1)
I have made a lot of incorrect assumptions, it seems like I did not bother to prove anything.2)
I was not thinking about the problem at all, I tried to guess my way through the whole process.
Good way to solve the problem
- Let's not rush, and instead of trying to solve the problem straight away, let's analyze what is happening in the problem.
- Let's look at the operation $$$a[i] = min(a[i], a[i+1])$$$.
- if $$$a[i] < a[i+1]$$$, then this operation is the same as just deleting $$$a[i+1]$$$
- if $$$a[i] \geq a[i+1]$$$, then this operation is the same as just deleting $$$a[i]$$$.
- So both players are basically deleting elements from the array each turn. Note that the first player cannot delete local maximum, and the second player cannot delete local minimum, but they never want to do that
- Let's rephrase the statement: We have an array $$$a$$$, $$$2$$$ players are deleting elements turn by turn. The first player wants the last remaining number to be maximum, the second player — minimum.
- It is obvious that the first player wants to delete small elements, and the second player wants to delete big elements. They take turns one after the other. In the end the remaining element will be somewhere in the middle.
- Let's be more specific. If there were $$$n$$$ elements in the array, then there were made $$$n-1$$$ operations before the array consisted of only 1 element. The first player will make $$$\lceil(n-1) / 2 \rceil$$$ operations and the second player $$$\lfloor (n-1) / 2 \rfloor$$$. If we sort the array in the non-decreasing order, the first $$$\lfloor (n-1) / 2 \rfloor$$$ and the last $$$\lceil (n-1) / 2 \rceil$$$ elements will be deleted. If we use 0-indexation, the remaining element will lie in $$$\lfloor (n-1) / 2 \rfloor$$$ index.
How to always solve problems the proper way
I think I can summarize the text above in the following way:
- In the bad solutions logical steps were huge, and most of the time they contained mistakes.
- In the good solutions I make small obvious steps that little by little get me closer to the correct solution.
You should always strive to solve problems the second way, but it is hard to be disciplined enough to do so. During the contests, there is always an incentive to rush and guess, because sometimes it leads to good performance. For me, the best way to deal with it is to record myself solving problems. It is quite boring to watch through it, but I make it interesting this way: I open a screencast of a highly rated participant, I watch him solve a problem in several minutes and then I ask myself "how on earth have I spent 20 minutes on the problem", and then I watch myself doing stupid things. And in the next contest I try to stop myself from repeating the same mistakes.
Shameless plug
If I somehow have not lost all of your respect by showing you my insane solutions to these problems and you still want me to teach you programming, send me a message on codeforces for more info, the first lesson is free (。◕‿‿◕。)
When I first read B, I immediately thought of binary search and replacing all numbers with $$$0$$$ and $$$1$$$. It was easier to understand what was going on, though it made me thinking more that the answer is the median. Btw this trick with replacing numbers with $$$0/1$$$ helps really much in E
A and B were too easy, skill issue mate sorry to say.
Imagine saying that to a master
really felt the need of haha emoji like facebook. Couldn't express it with down vote
Let me do it for you — 😂 😂 😂
wth man are you farming downvotes? Is it a thing now?
all downvotes from MASTERS
He is Master You Dumbo
Wow I did the same thing exactly as u in this contest bro. u can see my submissions I spent almost half an hour doing B and the result is I failed to finish D2 in contest time.
That is why I always skip the problem if I feel like I am stuck.
I remember one contest that was held while I was attending one programming training camp. I convinced guys from nearby hotel rooms to also participate in it, so it was quite funny that I managed to solve only $$$A$$$.
Later I upsolved that contest up to $$$F$$$, and all the problems seemed to be very solvable. And then it dawned on me, that I could have easily avoided that unpleasant experience — if I just skipped the annoying problem $$$B$$$. It would have felt a lot better if I managed to solve at least one difficult problem that day, even if I still lost rating.
So problem skipping is not only good for your rank, but it also helps you not to feel green while having a rough contest)
Good to know that it doesn't take too much IQ to reach master, just need to solve more !!
lmaoooooo, some masters or even GMs have 69 iq i guess
means we have hopes ;)
Nice blog
Small error : the better way of solving B isnt totaly correct. You claim that they are deleting elements but that isnt completely true, since you cant delete any element. However, any element thar you cant delete can never be optimal because Alice cannot delete a local maximum, which she anyways wouldnt since she wants maximum answer
After reading some of your comments, your thought process for solving problems is great!. An example problem would be "prime xor coloring". It seems like you very rarely guess which is what I would like to be able to do for most problems one day hopefully. Would love to see your screencasts or editorial in comments(like Yocycraft does) some day!
Thanks for your kind words. Depending on your definition of rarely, I guess rarely isnt very true, i would put it somewhere between 10 — 15%
I dont feel like additional editorials help people since there are already so many by so many others, but if you feel so, sure i can make it happen. Ill try to post short editorials under the contest announcement blogs next contest onwards
he almost write his thought process and observations in solution (comments)
pretty self explanatory and clean code i would say
Thanks for the reply. I don't think you need to do too many editorials. Around 10 div1+ div2 contests(for non-standard problems) should be enough. Others will disagree with the number but my point is at some point we will get a good idea of how you think about problems and after that the additional value of reading your editorials compared to just reading the official editorial might not be much.
Also, if you do decide to write editorials, I don’t think you need to do them in a detailed manner or similar to other editorials. Here are some of my suggestions if you are interested based on my experience and my guess about what people at my level struggle with.
I think for problems(Div2, A-D), I actually don’t have a hard time proving my solutions at all. But I take a long time(sometimes infinite) to find the right observations that leads to solutions and waste so much time making irrelevant observations. So far, for most problems(Example: 1979 C), I can’t think of a structured way/path that would lead me to making the right observations and the right hypothesis but once I make them proving them seems a lot easier.
I mostly guess different observations that comes to my mind and hope one of them works out. For example if a problem wants us to split into multiple segments, I just check if two or three segments is enough and then prove it as I have seen similar problems. Another example is for some constructive problems, I guess/hope that the solution is possible with lower or upper bound of the answer and then try to prove it and then construct. For almost all dp problems(Ex: 1987-D), I just try to guess the state and after that the rest of the problem is much easier and almost straightforward. So, for dp problems, you can write about how you arrived at the state and then write the transition and stop the editorial.
So, it would be more helpful if you wrote about the path that led you to making the right observations and you can probably tell to refer the official editorial for later steps.
take a look at this blog btw by Everule
https://codeforces.net/blog/entry/85172
I will try to do something similiar to what he did with more tasks i suppose
https://codeforces.net/blog/entry/133289
I included both of the problems you mentioned.
Thanks! I am sure it will be super helpful to me and many others.
Thanks again! I am trying to solve the problems myself first and then reading the blog to see your thought process. Btw, this time I found a greedy solution(with proof I believe) for problem (1987-D).https://codeforces.net/contest/1987/submission/279031851
Anyway my main takeaway so far is that I should most of the time try to solve problems with small jumps in logic that follows almost naturally(intuitively),otherwise after solving the problem or reading the editorial, I should figure out how could I have taken small jumps in logic to arrive at the solution in a methodical way rather than simply understanding the solution.
thanks! added a small note that clarifies that
My thinking about B is that Turtle is a max-min player while Piggy is a min-max player. So the two must want to control the boundary values. And this leads me to see the median value as an answer.
can you clarify that a little bit more?
It's very helpful.
wait im not the only out of competition participant to mald and bald on B!?!?
I made the exact same mistake in A as you and got 2 WAs after that re read the question and got AC XD , for B i just got it by observation in first try :)
Skill issue may be. Practice binary search. It will be better.
not mentioning problem C. I really hate problem of this kind, literally no one has time to do this level of analysis on actual contest. it's all about guess work and proof by AC otherwise you will behind of already 8000 contestant. if initial guess was wrong then it's over, get multiple WA, score goes down into drain receive -150 delta, unless able to upsolve like master of course.
So CP is all about no-brainer submissions?
Not exactly. I preferred losing time to getting penalty. So what I did is actually quickly implemented brute-force solution and found out if any of my suggestions are correct. Also, you can use the implemented brute-force solution to validate your implementation of a proper solution.
Shorten the solving time for A or even B in div2, I think that's normal for some coders (even myself), but sometimes to avoid penalty we have to check through the solution
I also did very bad in the contest, even worse than you, because you managed to solve D2 and I didn't.
I get stuck on A for a very long time, I misread the problem, thought the first letter and last letter also need to be different. I solved A 83 minutes after the contest begin and make 3 WAs.
And I also make a stupid mistake on D. For D1 I keep get TLE on pretest 24, and finally it turns out that I just pass the wrong parameter in my get_first_two_mex function, I pass the original list instead of the converted set. For D2 I make a false assumption and didn't do it till the end.
My performance in this contest is 1500+, much lower than my current rating. If I am a rated candidate master, I will drop more than 100 points.
I just want to say, everyone has its bad time. If you have a contest that give you more than 100 rating drop, don't be depressed because, it is not because you are much weaker than before, it is simply because this contest is not your case. Also, if you have a contest that give you +100, it is not because you are much stronger, it is simply because you are luck to come up with the solution very fast, you have the same brain as problem setter.
Because contest was created by the chinese!
I also misread problem A and won two WA
You just had a bad day, bro. It happens sometimes, but in my case it is normally amplified by a tilted state to make things even worse.
What a cancer in the comments section to a very nice blog. The blog is not about a bad performance, the blog is about how to avoid bad performances by actually methodically solving problems instead of trying to guess the solution.
When I was reading I was thinking "You would probably enjoy lessons from me", and then in the end there is a plug :) Fair enough :)
Agree, everyone is stuck behind how to solve the specific problems rather than noticing authors intentions.
what does WA2 Mean?
Wrong answer on test 2
I'd rather want to know how did you figure out how your mind works and paste it down as detailed as this.
I tried to do the same work before (try to summarize my mistakes in the contest) and ended up writing a bunch of complete nonsense.
I recorded myself solving the contest and I have a habit to speak out loud while I think.
In the past I tried to analyze what notes I took during the contest, but it was very hard to make sense of it.
I did this thing of recording myself and compering my screencast to someone high rated several times, that is why I have so many notes under the code in all of my submissions. There I tried to summarize all of the mistakes I make. But it turns out it is not as useful as I hoped it would be: the more things I added, the harder it became to control any of the bad habits.
Now I try to focus on 1 particular bad habit that annoys me that day the most. But even then, every time something goes wrong in a contest, my autopilot turns on and I repeat the mistakes I always do for the 100 time.