### Topcoder SRM 496, D1, 500-point problem

Read over the problem. When I looked at this, my first thought was to solve it recursively. Write the recursive procedure cvg(int v, int index), which counts the number of valid guesses for velocity v, supposing that all balls in firstPicture whose indices are less than index have been matched with balls from secondPicture, and those matches have been noted somehow.

The basic outline of cvg() will be:

 ```long long OneDimensionalBalls::cvg(int v, int index) { long long rv; rv = 0; for (i = -1; i <= 1; i += 2) { if (firstPicture[index]+v*i is in secondPicture) { if (index+1 == firstPicture.size()) { rv++; } else { remove the ball from secondPicture that equals firstPicture[index]+v*i; rv += cvg(v, index+1); put the ball back } } } return rv; } ```

This solution will work for small sizes, but the fact that it returns a long long should clue you in that something isn't right. Regardless, it's worth hacking up for practice. Here is a first pass, in ODB_Rec1.cpp. First, I save firstPicture and secondPicture as FP and SP. That way, my recursive procedure always has access to them. I also have two more members: Matched is a vector, which is the same size as SP. If Matched[i] is true, then element i of SP has been matched from a previous call to cvb. SP_Balls is a map such that if SP[i] = j, then SP_Balls[i] = j. It lets us find out quickly whether a ball with a given value is in SP.

 ```class OneDimensionalBalls { public: long long countValidGuesses(vector firstPicture, vector secondPicture); long long cvg(int v, int index); vector FP; vector SP; vector Matched; map SP_Balls; }; ```

Given that backdrop, cvg works as above, except it fills in the pseudo-code with code that uses Matched and SP_Balls:

 ```long long OneDimensionalBalls::cvg(int v, int index) { long long rv; int second_val, sb_index; map ::iterator mit; int i; rv = 0; for (i = -1; i <= 1; i += 2) { second_val = FP[index]+v*i; mit = SP_Balls.find(second_val); if (mit != SP_Balls.end() && !(Matched[mit->second])) { if (index+1 == FP.size()) { rv++; } else { Matched[mit->second] = 1; rv += cvg(v, index+1); Matched[mit->second] = 0; } } } return rv; } ```

Finally, the code for countValidGuesses() needs to set up FP, SP, Matched and SP_Balls, and just for testing, it calls cvg with a velocity of one:

 ```long long OneDimensionalBalls::countValidGuesses( vector firstPicture, vector secondPicture) { int i; FP = firstPicture; SP = secondPicture; Matched.resize(SP.size(), 0); VIT(i, secondPicture) SP_Balls[SP[i]] = i; return cvg(1, 0); } ```

To compile and run this, I use my standard topcoder-programming trick of having a driver program that includes this program and runs the examples. This is in SRM-496-Driver.cpp. To compile, you need to copy your program to OneDimensionalBalls.cpp, and then simply compile SRM-496-Driver.cpp:

```UNIX> cp ODB_Rec1.cpp OneDimensionalBalls.cpp
UNIX> g++ SRM-496-Driver.cpp
UNIX>
```
With example zero, we have:

 ```FP = { 12, 11 } SP = { 10, 11, 13 } ```

Thus, when v=1, we should have two sets of legal guesses: 11 goes to 10 and 12 goes to either 11 or 13. When we run it, it gives us the correct answer:

```UNIX> a.out 0
2
UNIX>
```
You can also call a.out with -1 as an argument, and that allows you to put the two vectors of integers on standard input:
```UNIX> cat tmp.txt
12 11
10 11 13
UNIX> a.out -1 < tmp.txt
2
UNIX>
```
Now, what velocities should we use? The only ones that will be legal are velocities equal to the difference between each ball in SP and FP[0]. The code to enumerate these uses a set, because you don't want to test the same velocity twice (in the example above, the differences are 2, 1 and 1) (code in ODB_Rec2.cpp):

 ```long long OneDimensionalBalls::countValidGuesses( vector firstPicture, vector secondPicture) { int i, d; set velocities; set ::iterator vit; long long rv; FP = firstPicture; SP = secondPicture; Matched.resize(SP.size(), 0); VIT(i, secondPicture) SP_Balls[SP[i]] = i; VIT(i, SP) { d = SP[i] - FP[0]; if (d < 0) d = -d; if (d != 0) velocities.insert(d); } rv = 0; IT(vit, velocities) rv += cvg(*vit, 0); return rv; } ```

When we run this, it works on all the test cases:

```UNIX> cp ODB_Rec2.cpp OneDimensionalBalls.cpp
UNIX> g++ SRM-496-Driver.cpp
UNIX> a.out 0
3
UNIX> a.out 1
0
UNIX> a.out 2
1
UNIX> a.out 3
6
UNIX> a.out 4
7
UNIX>
```
So compile and submit???? You should be worried. Each recursive case can make two recursive calls, and if there are roughly 25 levels of recursive calls, your code may take on the order of 225 operations. That's too much. Indeed, when I compiled and submitted, it choked on the following input:

 ```FP = { 9, 10, ..., 39, 40 } SP = { 1, 2, 3, ..., 49, 50 } ```

I put that into case 6 in SRM-496-Driver.cpp, and "a.out 6" takes much longer than the requisite 2 seconds. Dang, back to the drawing board. At least we've had some more practice with maps and sets.

When you learn about dynamic programming later, you'll see that memoization doesn't work here either.

### Giving the problem more thought.

Instead, let's think more about the problem. Again, we'll restrict our attention to velocity v. Each ball in FP can be matched to zero, one or two balls in SP. If zero, then there's no valid guess. You can return zero. If one, there is only one potential valid guess, and you can remove the ball from FP and remove its corresponding ball from SP. At this point, you can also remove all balls from SP that don't match to any balls in FP. Let's take a look at such a system. Example 4 from the problem suffices:

 ```FP = { 2, 4, 6 } SP = { 1, 2, 3, 4, 5, 7, 8 } ```

We have 5 potential values of v: 1, 2, 3, 5 and 6. I draw the SP and their matching FP for the first four of these below:

Let's consider the simplest: v=5. In this case, 4 cannot be matched to anything, so there are zero valid guesses. (The same is true of v=6, which is not drawn).

Next, let's consider v=2. In this case, 2 and 4 match to one number in SP. We can thus remove them from the system. When we do so, 6 matches to one number, and we remove it. We are left with an empty system. That corresponds to one valid guess.

How about when v=3? Here, 2 and 6 each match to one number, so they can be removed from the system. We can also remove any balls in SP that don't match any balls in FP (at this point, the only ball in FP is 4), so we're left with:

There are two ways to perform this match, so there are two valid matches. The last case is v=1, which requires a little more thought. Let's look for a pattern. When we have a system that looks like:

As we said above, this corresponds to two valid guesses. Let's make it a little more complex:

If we have the leftmost number in FP match the leftmost in SP, then there are two ways to match the remaining elements (since it's equal to the previous picture). If we have the leftmost number in FP match the second element in SP, then there is just one way to match the remaining element. That makes three ways in total.

Let's make it a little more complex still:

If we have the leftmost number in FP match the leftmost in SP, then there are three ways to match the remaining elements (since it's equal to the previous picture). If we have the leftmost number in FP match the second element in SP, then there is just one way to match the remaining elements. That makes four ways in total.

Do you see the pattern? If you have a set of n elements in FP, then they will match to the elements in SP in n+1 ways. Thus, the v=1 case in Example 4 has four matches. The answer to example 4 is thus 4 + 1 + 2 = 7.

If we have multiple sets of matching elements, we have to multiply their number of guesses. For example, suppose we have:

The first set matches in two ways, the second in four, and the third in three. Thus, the total number of matches is 2*4*3 = 24.

Let's take one final concrete and complex example to make sure that we understand. Suppose our system looks like:

The first thing that we do is remove the numbers in FP (4, 15 and 22), that only match one number in SP. We also remove their matches in SP:

We're left with more numbers in FP (2 and 20) that only match one number in SP. We keep removing them and their corresponding numbers in SP until we only are left with numbers that have two corresponding numbers in SP:

From our discussion above, this one has four ways to be matched.

### Turning this into code

Now we know what we want to do -- we have to code it up. I think that a good way to start is to represent each ball as its own instance of a Ball class. We'll define it:

 ```class Ball { public: int val; Ball *low; Ball *high; }; ```

Val is its value, and low and high are pointers to other balls. If b is in FP, then low points to the ball in SP whose values is b->val-v. If there is no such ball, then it is NULL. Similarly, b->high points to the ball in SP whose values is b->val+v. If there is no such ball, then it is NULL.

The balls in SP point to the balls in FP. To be precise, If b is in SP, then b->low points to the ball in FP whose values is b->val-v. If there is no such ball, then it is NULL. b->high is defined similarly.

When we call cvg() we just call it with a velocity. We then set up the balls and their pointers. Then, we do the following:

• Check all the balls in FP. If any don't have a valid low or high, then return 0, becuase there is no valid guess.

• Check all the balls in FP. If any ball b has just one valid low or high, then remove it and the ball in SP that it points to. In doing that, you may have to remove other pointers, becuase there may be another ball pointing to the ball in SP.

• Keep repeating this step until the only balls in FP have two pointers. Now, identify all the sets of balls like those in the last picture, determine how many valid guesses correspond to each, and multiply them.