SRM 382, D1, 250-Pointer (CollectingRiders)

James S. Plank

Thu Nov 14 14:35:02 EST 2013
Updated: Thu Oct 22 17:06:16 EDT 2020

In case Topcoder's servers are down

Here is a summary of the problem:

The examples


Testing yourself

Like the Cryptography Problem, I have a shell script tests.sh, that you can use to test your program. When you run tests.sh, your answer should be identical to answers.txt.

Hints

Consider a "rider", and suppose that he can only do one jump per move. Then you can view the squares on the board as nodes on a graph, and you need to find the shortest distance from the rider's initial square to each square. The edges are knight moves. Therefore, in example zero, the graph is drawn below (I've colored the edges to make them easier to distinguish from one another):

Now, determine the shortest path from the rider in the upper right-hand corner to every other node:

And determine the shortest path from the rider in the lower left-hand corner to every other node:

Recall that this rider can do one or two jumps in every move. That means you can convert those shortest jumps to shortest moves by adding one and dividing by two. Why? Well, consider a node that a 1-rider can reach in two jumps. That means a 2-rider can reach it in one jump. (2+1)/2 = 1. Now, consider a node that a 1-rider can reach in three jumps. That means a 2-rider can reach it in two jumps. (3+1)/2 = 2. See how the math works? You'll have to derive the math for each kind of rider (it's not complex). Here is the graph for the 2-rider:

I'm going to redraw the two graphs here side by side -- the left one is the rider in the upper-right corner, and the right one is the rider in the lower-left corner:

For each node, add the two shortest distances. When you're done, you can see that the minimum node is two (there are two of them, and you can verify by hand that they work):

That gives you a nice roadmap towards solving this problem with BFS. Think about running time. Each BFS is O(|V|+|E|), which is O(r*c). There are up to r*c riders, so you have to do up to r*c BFS'. Therefore, the total is O(r*c*r*c). Since r and c are limited to ten, this is not a problem (and it's why I bumped it up to 30 in tests.sh).

When you're hacking up the BFS, think about how you want to represent the graph. I didn't represent edges explicitly. I simply simulated each jump when I processed a node during the BFS.