Hints for TCCO 2005, Qualification 1, 500-Pointer (LandMines)

James S. Plank

Fri Oct 23 11:41:17 EDT 2015
Problem Statement.
The key in this problem is to turn the instance of a problem into a directed graph, where there is a node for each square, and an edge from square a to b if the soldier can walk from square a to b without detecting a sensor in that direction.

Then the problem is to identify all of the squares reachable from the first square and count them. This is a connected component problem, which you solve with depth-first search.

Some of you get confused with the part of the problem statement that says "he will not move onto a square if his sensor beeps when pointed in that direction, unless he has previously visited that square." That doesn't mean that you should put an edge from b to a if there is an edge from a to b. It just says that you can backtrack on your depth first search.

Let's take example zero. Here's the graph:

I'm drawing the mines red, and nodes that you can reach from the starting square yellow. The other nodes are blue. Even though the graph above has edges into the starting node, there are none coming out, so there are no other nodes that you can reach from the starting node. The answer is one.

Here are the other examples. In all of them, you discover the yellow nodes by doing a DFS from the starting node.

Example 1:

Example 2:

Example 3:

Now, how you represent your graph and do the DFS is up to you. If you want to implement adjacency lists in the nodes, you can do that. That may well be the best way to do it. An adjacency matrix will work, because the constraints of the problem are small, but I believe it will make your life harder rather than easier.

You may want to represent a node with a single number -- that way it's easy to store the node on the adjacency list. In fact, were I solving this problem anew, I would probably have two vectors, both of size layout.size()*layout[0].size().

I'll initialize my states so that states[i] = layout[i/layout[0].size()][i%layout[0].size()].

Then, I'll go through each row and column and add links to the adjacency lists, so that the graph is built.

I'll do a DFS to find the connected component containing node 0. I'll use the states fields for the visited field, changing state to '.' when I visit a node.

Finally, I'll count the '.' states and return the sum.