UVa Online Judge Challenge "572"

Although BFS and DFS were recommended solutions to the problem, I saw an opportunity to solve this problem using Disjoint Sets. The virtual judge run time was 0.050s.

Problem

My Solution

  1import java.io.BufferedReader;
  2import java.io.IOException;
  3import java.io.InputStreamReader;
  4public class Main {
  5    public static void main(String[] args) throws IOException {
  6        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  7        while (true) {
  8            String[] dimensions = br.readLine().split(" ");
  9            int rows = Integer.parseInt(dimensions[0]);
 10            if (rows == 0) {
 11                System.exit(0);
 12            }
 13            int cols = Integer.parseInt(dimensions[1]);
 14            int size = rows * cols;
 15            DisjointSet ds = new DisjointSet(size);
 16            byte[] flattenedGrid = new byte[size];
 17            /*
 18            |* This is a 2D grid of characters that I am flattening into a 1D byte 
 19            |* array. There are only two bytes that I am concerned with: 42 and 64.
 20            |* 64 represents an oil deposit whereas 42 represent the absence thereof. 
 21             */
 22            for (int x = 0; x < rows; x++) {
 23                System.arraycopy(br.readLine().getBytes(), 0, flattenedGrid, x * cols, cols);
 24            }
 25            /*
 26            |* "Stand" on every position of the grid. If you are standing over
 27            |* oil, look in every direction around you for an adjacent
 28            |* oil deposit. Every time oil is spotted adjacent to where you are
 29            |* standing, union your position and that position into the same set.
 30             */
 31            for (int x = 0; x < rows; x++) {
 32                for (int y = 0; y < cols; y++) {
 33                    int[] directions = new int[]{-1, -1, -1, -1, -1, -1, -1, -1}; //8 directions
 34                    int position = x * cols + y;
 35                    if (flattenedGrid[position] == 64) { //If you are standing on an oil depost
 36                        if (x > 0) {
 37                            directions[1] = ((x - 1) * cols) + y;//north
 38                        }
 39                        if (y < cols - 1) {
 40                            directions[2] = ((x - 1) * cols) + y + 1;//north east
 41                            directions[3] = position + 1;//east
 42                            directions[4] = ((x + 1) * cols) + y + 1;//south east
 43                        }
 44                        if (y > 0) {
 45                            directions[0] = ((x - 1) * cols) + y - 1;//north west
 46                            directions[6] = ((x + 1) * cols) + y - 1;//south west
 47                            directions[7] = position - 1;//west
 48                        }
 49                        if (x < rows - 1) {
 50                            directions[5] = ((x + 1) * cols) + y;//south
 51                        }
 52                        /*
 53                        |* This loop does the actual comparisons and
 54                        |* if both positions have oil, unions them.
 55                         */
 56                        for (int i = 0; i < directions.length; i++) {
 57                            if (directions[i] >= 0 && directions[i] < size) {
 58                                if (flattenedGrid[directions[i]] == 64) {
 59                                    ds.union(position, directions[i]);
 60                                }
 61                            }
 62                        }
 63                    }
 64                }
 65            }
 66            /*
 67            |* Now that the algorithm is finished, I count the number of
 68            |* disjoint sets. This represents the number of distinct oil deposits. 
 69             */
 70            int[] counter = new int[size];
 71            int distinctOilDeposits = 0;
 72            for (int i = 0; i < size; i++) {
 73                if (flattenedGrid[i] == 64) {
 74                    int cursor = ds.find(i);
 75                    if (counter[cursor] == 0) {
 76                        distinctOilDeposits++;
 77                        counter[cursor]++;
 78                    } else {
 79                        counter[cursor]++;
 80                    }
 81                }
 82            }
 83            System.out.println(distinctOilDeposits);
 84        }
 85    }
 86}
 87class DisjointSet {
 88    int parent[];
 89    DisjointSet(int size) {
 90        parent = new int[size];
 91        int i;
 92        for (i = 0; ++i < size;) {
 93            parent[i] = i;
 94        }
 95    }
 96    int find(int n) {
 97        return n == parent[n] ? n : find(parent[n]);
 98    }
 99    void union(int x, int y) {
100        parent[find(x)] = find(y);
101    }
102}