At first I tell about the contest at all.
And now let's start analysis.
Problem A (div.2) - Restoring Password
Password was very easy to restore. You should just iterate over groups of 10 characters in the first string and over all codes. Then, if some number's code is equal to the group - print that number.
Here's the example: http://pastebin.com/hMV0NcjN
Problem B (div.2) - Friends
Let's construct the graph where vertices correspond to the people and edges correspond to the relationships. Then paint each edge in this way: edge will be red if the men connected by it are friends and black otherwise. Now let's think what is "three pairwise acquainted people" and "three pairwise unacquainted people". We see that they are cycles of only red and only black vertices correspondingly, and the length of these cycles is 3.
Now we know the solution: write 3 "for" cycles, one cycle for one vertex, and check if the edges between these vertices are only red or only black.
Here's the solution: http://pastebin.com/gswaxGmM
Another way to solve it is to notice the answer is FAIL if and only if graph has exactly 5 edges and they all together form a cycle with a length 5. It's very funny solution, I think. Here's the code: http://pastebin.com/09T0ixrJ
Problem A (div.1) / C (div.2) - Frames
So let's solve the problem. At first notice that the answer is not greater than 3 because we always can do three selections (maybe, some of them are empty): with first selection we select end of the first row, with second one - begin of the last row, and with last one - all remaining folders (they form the rectangle).
The best way is to find all cases with answer 1 and 2. Try to do it.
If the answer is 1, we can select all folders from a to b with one selection. There must be nothing hard to detect these cases:
- first and last folders are in the same row (21 5 7 9);
- first folder is in the first column, and the last folder - in the last column (21 5 1 15), сase m = 1 is included here;
- first folder is in the first column, and the last folder is n (21 5 6 21). Case when we must select all folders is included here. I was very surprised when I saw that many contestants forgot about it.
And these are the cases with answer 2:
- first and last folders are in the adjacent rows (21 5 8 14);
- first folder is in the first column (21 5 6 13);
- last folder is in the last column (21 5 4 15);
- last folder is n (21 5 4 21);
- and another tricky case: if the column where first folder is located is just at right from the column where the last column is located (21 5 3 12).
If no one of these conditions is true, answer is 3.
Here's the solution: http://pastebin.com/8QRytzzF
Problem B (div.1) / D (div.2) - End of Exams
Greedy algorithm solves this problem. We should consecutively try to pour milk from each bottle into each available cup and in maximal possible amount.
Also we always need to know, how much milk is in each bottle and each cup, for each cup - bottles from which we have poured milk, and for each bottle - cups into which we have poured milk.
Writing it is not hard. But where is one special moment - if we compare real numbers, we must use EPS, or we can get WA on test 12 (50 1000 49). Some programs write NO on this test while answer is YES, because of wrong comparing of real numbers.
It must be said that answer can be calculated in integers: just set the volume of milk in each bottle mn. And only when we will print the answer, we divide each volume by mn and multiply by w. All three jury solutions didn't think up this :)
Problem C (div.1) / E (div.2) - Azembler
I don't know why so few coders have solved it. Small limitations for n and big time limit - 5 seconds - hint that it's backtracking. Also, no need to be a soothsayer to understand that maximal answer is about 5.
Solving it is clear. You should keep all current registers at the vector and call some function that goes over all current registers and calculate new values, then calls itself recursively. In that process we can also save the program itself.
There are some hacks to speed up this approach: for example, iterate over numbers in descending order (it works faster), but 5 seconds is such TLE that you can solve it any way. Or you can launch backtracking for the specific answer (increasing it) while the program won't be found (I don't know how this method is named in English). Also, some contestants have solved it using BFS.
Here are two solutions: standard backtracking (http://pastebin.com/Z6ZF36st) and backtracking for the specific answer (http://pastebin.com/viiYF9CB).
Problem D (div.1) - Flags
I think my solution is not optimal, it's too long. Many solutions submitted during the contest are shorter. But I tell you about my solution.
At first I solve the problem for the number of stripes equals N (or L = R).
Let![](https://espresso.codeforces.com/9621ef8d5edb86362dcec51e61f085a2263c9fc2.png)
At first sight it seems that answer is
![](https://espresso.codeforces.com/ce8da7698b7b0a5d82a8c65d376451d6ca01051b.png)
So for the flags with even number of stripes formula is correct, because there are not palindromes among them. And if N is odd, the correct formula is
, where
is the number of palindromes with N stripes. Each palindrome is definited by its first
stripes, and we can write that
.
Let's use dynamic programming. As a state we can take a vector
![](https://espresso.codeforces.com/295f8eac4e826d7c91037ab028edd66992db1d8e.png)
![](https://espresso.codeforces.com/06f03217a754789d2480c1ca2c1247555a6a5b2e.png)
As start state we can take vector
![](https://espresso.codeforces.com/30f303ca299c14d33d6a944b9d1193e841bf3960.png)
![](https://espresso.codeforces.com/295f8eac4e826d7c91037ab028edd66992db1d8e.png)
It turns out that there is some matrix A that
![](https://espresso.codeforces.com/146bfd72677b3dce326fc9f61acdf5b75ef73670.png)
We're about the finish. It's obvious that
![](https://espresso.codeforces.com/394f57deba66448e718f367aff2a7c19c4669af2.png)
But it was only problem where L = R. Let's find a solution for the segment
![](https://espresso.codeforces.com/e72a6628091297fbd620239a22c552019512f9da.png)
I know two ways to do it. First way is to add a new component to the vector and new row and column to the matrix. This new component should keep the total number on the segment
![](https://espresso.codeforces.com/decd2237334dd88c5f3aa738c3d4b5a8032f29d6.png)
I like the second way. As we did it earlier, we will find a number of flags where symmetrical ones are different, but on the segment
![](https://espresso.codeforces.com/e72a6628091297fbd620239a22c552019512f9da.png)
![](https://espresso.codeforces.com/4ce9f3e037586b3d8c70e89bba59550655ab25d5.png)
Let b is such maximal power of 2 that 2b - 1 ≤ N. We can write
![](https://espresso.codeforces.com/5b98dbd1da991b7486d1ad3f076c5ff056372a42.png)
And apply some math magic to the first part of the previous formula:
![](https://espresso.codeforces.com/e917c60b03d8556ec92f204ed0636155fb5372ab.png)
We forgot about the palindromes, but it's very easy to calculate their number. Let's suppose that L and R are odd (if they are even, we can add one to L and substract one from R). Then
![](https://espresso.codeforces.com/2e122e1a4ffac11012deb3c6ccc4b9fb5a475a73.png)
That's all. Don't forget to apply "mod" operation after each operation and examine border cases carefully. And here's the solution: http://pastebin.com/wHu1tPgd (yes, "matrix" and "vector" type definitions are strange - I've totally forgotten how to write in Pascal)
Problem E (div.1) - Lostborn
This problem can be solved using inclusion-exclusion principle. If is the answer, then the following formula works:
. But if you write only this recursive function, you get TLE. Many contestants got TLE and were hacked because they didn't run maximal test on their computers.
And the others who sensed that something was wrong memorized the answers for small n and all ai. For example, you can see solution by rng_58 who won the contest, or this solution: http://pastebin.com/4kcfJdAi.
Sorry for my English :)
At the beginning, v=0.
Bottle 1: v=0. Pour 3/4 into cup 1 and 1/4 into cup 2.
Bottle 2: v=1/4. Pour 2/4 into cup 2 and 2/4 into cup 3.
Bottle 3: v=2/4. Pour 1/4 into cup 3 and 3/4 (= 0) into cup 4.
It's similar if we pour 3/4 of 3 bottles into 3 cups and the rest 1/4 of 3 bottles into the other.
So, divide it into 2 progresses.
1. Make n cups full with n bottles. Each bottle remains the same volume of milk.
2. Make the other m-n cups full. So n%(m-n)=0 is the condition.
Here is another proof for the greedy algorithm:
Let's forget w, and declare that each bottle contains m/n cups.
If n<m, then each bottle must be poured in two cups.
Consider the following graph:
Nodes are cups, and two cups are connected if they are filled using a common bottle.
The graph has m nodes, n edges. Consider a connected component, c its number of nodes. c cups need c*n/m bottles to be filled. On one hand, c*n/m<c, and on the other hand, there are at least c-1 edges. In the end, each connected component must be a simple path. Pouring in the order of each simple path is exactly the greedy algorithm.
Author said:
If N is odd, the correct formula is
which means ans(N) = f(N) / 2 + f((N + 1) / 2) when N is odd.
but actually, ans(N) = (f(N) + f((N + 1) / 2) / 2
DIV-1 (A)
in the first sample you can select the folders with 2 frames
you need to select folders (3,4)
then you can select folders from 5 to 9....
i saw the tutorial for this problem and i saw:
"and another tricky case: if the column where first folder is located is just at right from the column where the last column is located (21 5 3 12)"
i think this case could explain my solution for the first sample...