import java.util.*;
import java.io.*;

import static java.lang.System.*;

public class Mazes {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(new File("mazes.dat"));
        int times = input.nextInt();

        while (times-->0) {
            int n = input.nextInt();
            char[][] maze = new char[n][n];

            input.nextLine();
            for (int i = 0; i < n; i++) {
                maze[i] = input.nextLine().toCharArray();
            }
            int start = 0; // find the col coordinate of the start (row coordinate is always 0)
            while (maze[0][start] == '#') start++;

            // at this point, we have n, the maze, and the starting point

             // The trick to solving mazes quickly is an algorithm called
             // breadth first search, or BFS.
             //
             // The idea is this:
             // if you have already found the region of spots in the maze that can be reached in m or fewer
             // steps, you can easily find all the spots reachable in m+1 steps just by stepping off
             // the region from the spots that require m steps to be reached. We can execute the process
             // again to find the region reachable in m+2 spots, and again to find m+3 spots
             // and so on, until we have reached the end of the maze. If m = 0, the beginning region is only
             // the start, so this execution will run from the start to the finish.
             // There is a sample execution document to help you visualize.

            int [][] dists = new int [n][n]; // this stores the distances of all the points in the maze from the start
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    dists[i][j] = Integer.MAX_VALUE / 2; 
                    // set all the distances to infinity (or close enough) since we don't know them yet...
            dists[0][start] = 0; // ...except for the start, which is obviously take 0 steps to reach

            LinkedList<Integer> farthest; // This queue is used to store the farthest points from the start
                                          // You don't have to write a pair class to store coordinates if
                                          // you add and remove the coordinates in pairs
            farthest = new LinkedList<>();
            farthest.addLast(0); // push the row coordinate of the start
            farthest.addLast(start); // push the col coordinate of the start

            while (true) {
                int r = farthest.pollFirst(); // get the row coordinate of the farthest point
                int c = farthest.pollFirst(); // get the col coordinate of the farthest point

                // now that we know the farthest point, we just step in all four possible direction
                // if we can (i.e. we don't step off the maze, into a wall, or onto a point already visited)

                if (r != 0 && maze[r-1][c] != '#' && dists[r-1][c] == Integer.MAX_VALUE/2) {
                    // if this isn't the top edge of the maze, there isn't a wall upward, 
                    // and the spot upward isn't visited,
                    // record the distance of that spot and add it to the queue

                    dists[r-1][c] = dists[r][c] + 1;
                    farthest.addLast(r-1);
                    farthest.addLast(c);
                }
                if (c != 0 && maze[r][c-1] != '#' && dists[r][c-1] == Integer.MAX_VALUE/2) {
                    // visit spot to the left
                    dists[r][c-1] = dists[r][c] + 1;
                    farthest.addLast(r);
                    farthest.addLast(c-1);
                }
                if (c != n-1 && maze[r][c+1] != '#' && dists[r][c+1] == Integer.MAX_VALUE/2) {
                    // visit spot to the right
                    dists[r][c+1] = dists[r][c] + 1;
                    farthest.addLast(r);
                    farthest.addLast(c+1);
                }

                if (r != n-1 && maze[r+1][c] != '#' && dists[r+1][c] == Integer.MAX_VALUE/2) {
                    // visit the spot downward
                    if (r == n-2) { // this implies that we have reached the end of the maze
                        out.println(dists[r][c] + 1); // so print the distance and finish
                        break;
                    }
                    dists[r+1][c] = dists[r][c] + 1;
                    farthest.addLast(r+1);
                    farthest.addLast(c);
                }
            }
        }
    }
}

results matching ""

    No results matching ""