Post date: Sep 15, 2014 1:13:44 AM
Problem set and code. Original here. It is assumed the reader has at least read the problems.
Since the paperboy can carry as many papers as he wants, we can rule out any kind of path that zig-zags between the houses in relation to the starting position. To see this, observe that if we start between two houses and go to the left (where we assume the houses to be on a left-right line), we need to visit the houses further to the left eventually, and so there's no reason to not do it immediately instead of going back to the house to the right.
Also, note that as the delivery time is 1 is constant for all houses, we can instead assign an instantaneous delivery time and just add n to our answer at the end. So we have two scenarios:
Note that we could potentially start off left of the leftmost house, or right of the rightmost house, so the absolute difference should be taken.
The winner of the tournament must have won N times; the second place finisher must have won N-1 times. If we keep track of who beats whom, using a map of a name of a person to names of the contestants beaten by that person, then we can combine the two sets of beaten contestants, one for each finalist, and sort that alphabetically to get the repechage.
If we make separate triangles out of the happy people and unhappy people, and the triangles don't intersect, we have a line that can fit in between the triangles and separate the two sets successfully. If they do intersect, we can't draw this line. Now, all we need to do is see if the triangles intersect - which might be harder than you think since apparently the polygon intersection code in the code archive is broken...
Alternatively, you could do what I did and create trial lines composed of two points from the same set. Take this to be the wall. (We are guaranteed no three points are colinear, so it's okay for the line to be directly on the two points, since we can move the line just off the points without messing anything up.) Now, the third point that isn't part of the wall must be on the opposite side of the three points of the other set, so we extend the wall to be a super long line segment, create a second line segment from the third point and a point from the other set, and see if those line segments intersect. If we get three line segment intersections out of three points, the wall is valid.
Note that the sum of the pile sizes must be a power of 2, so if there are any piles with size congruent to 1 (mod 2), then there must be an even number of them. If we run the difference operation on all of these, we'll end up with a bunch of new piles, where all their sizes are 0 mod 2. Now if there are any piles with size 2 mod 4, there must be an even number of them, so we can run the difference operation on those, and so on for each increasing power of 2. We'd also want to combine similar piles whenever possible, since multiplying a pile size by 2 won't destroy any previous progress. In the worst case, we'd require 100 difference operations for 31 different bits, and 199 combine operations, which is well under the 10000 operation limit.
This is the "good", deterministic, consistent solution; I will now describe mine (which, mind you, got accepted) which is nothing of the sort. Potentially, this is more illuminating since I'll describe my thought process of actually solving the problem, but you can safely skip ahead to the next problem if you don't want to read my rambling.
So we start off with N piles, and our objective is to reduce them all to one. Clearly, the combine operation is ideal, as it permanently reduces the number of piles. If we can't do a combine, we'd want to somehow be able to run a difference operation, possibly many times, to get two equal pile sizes. The easy way would just be to randomly pick two indices to perform a difference operation on, but we might run into problems with time and the number of moves made; can we do better?
It turns out that if we have two unequal numbers that happen to sum to a power of 2, and we run the difference operation on them repeatedly, we'll eventually get two equal numbers. Why does this happen? I have no idea, and in a contest environment, I won't really care about a hard formal mathematical proof1; all I did was try this for every pair of numbers summing to 64, notice it worked with a maximum of 6 moves (note 26 = 64), then said it was good enough.
If this doesn't work, then we resort to picking two random numbers and running difference on them. So the control flow looks something like:
The rationale behind this is that checking distinct pairs is quite fast (200 choose 2 = 19900), and running difference randomly is bound to eventually satisfy one of the two previous checks. In practice, this runs very quickly (all test cases are done in <0.8 seconds), and the maximum number of moves done for a test case is somewhere around 4-5 thousand. Obviously, randomization doesn't usually work, so take all this with a grain of salt, but in this case it happened to work and (maybe?) was the faster solution to figure out and code.
One extremely important subtle fact is that you don't actually have to find the minimum length solution, across all possible solutions. You only have to supply any one solution that gets out of the maze for every possible entry and exit and boulder configuration, that fails to get out of the maze for every possibility if the last character is removed. So if we had a valid string, we could run through every possibility and note the index at which we finish the maze, then take the maximum index and trim the string to that point.
Here is the deterministic solution, courtesy of Kent and Jason. Consider a maze as a graph, where tiles without boulders on them are nodes and valid paths between them are edges. Now, for every possible boulder configuration2:
However, even though this seems all nice laid out in a list, as Jason's code demonstrates, it's really not that nice.
Here is an alternative, a non-deterministic solution courtesy of Paul, which (as most non-deterministic solutions are in programming contests) is probably not the intended solution, but is (at least in this case) much simpler. We can simply generate a string of 1000 random moves, and then trim the string to obtain a solution.
The key observation is that 1000, the string length limit, is a very large number compared to 9 and 12, the number of nodes and edges in the 0 boulder maze. For actual theory, it is known that the expected number of moves before a random walk hits all vertices of a connected graph is 2|E|(|V|-1), which is basically the "Paul discovered this when learning about randomized 2-SAT algorithms" theorem. In any case, it makes some intuitive sense; if we do a lot of random moves in a small maze, we'll be able to reach any point from any other point, regardless of boulder configuration. And since we can make up to 1000 moves, we'll be almost certain to satisfy the required condition, so we're already almost done: all we need to do is trim the string (and if we're really paranoid, keep creating random strings until the condition is satisfied).
This is "just" a DP, courtesy of Paul. The goal is to match the given substring to the randomly typed string, and there are two states:
If we match all of the substring, then any characters past that point can be anything, so that's 36 to the power of the number of letters remaining. If there aren't enough letters remaining in the random string, we can't match anything and return 0. Otherwise, we can brute force all the possible characters (a-z, 0-9) to attempt matching the next character in the substring:
Then the answer is the value at the state (0,0).
I haven't mentioned the mod 100003 requirement, because it's not that big of a deal; since 100003 is prime, we can mod all intermediate values with it without any trouble.
Obviously, this is a bit more difficult than I make it out to be, so if you're stuck at this problem hopefully you're inspired to code up a solution, which (big secret here) is actually how to improve at programming competitions, since you actually have to implement solutions that you think of.
1Some discussion with Karlming reveals that one could probably do an inductive proof on increasing powers of 2, where the trivial base case is 1 and 3, and in the inductive step if your numbers are both even you can divide everything by 2 and if they're both odd you can run the difference operation once to get two even numbers. Or something like that. Details left to reader.
2This can be represented as a 9-bit bitmask.