• + 0 comments

    By using a map of valid locations, you can avoid bounds checking.

    import java.io.*;
    import java.math.*;
    import java.security.*;
    import java.text.*;
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.function.*;
    import java.util.regex.*;
    import java.util.stream.*;
    import static java.util.stream.Collectors.joining;
    import static java.util.stream.Collectors.toList;
    
    
    class Node {
        int x;
        int y;
        int choices;
        public Node(int x, int y, int c) {
            this.x = x;
            this.y = y;
            this.choices = c;
        }
        
        @Override
        public boolean equals(Object o) {
            Node n = (Node) o;
            return (n.x == x && n.y == y && n.choices == choices);
        }
        @Override
        public int hashCode() {
            return x * 129 + y * 47 + choices;
        }
    }
    
    
    class Result {
    
        /*
         * Complete the 'countLuck' function below.
         *
         * The function is expected to return a STRING.
         * The function accepts following parameters:
         *  1. STRING_ARRAY matrix
         *  2. INTEGER k
         */
    
        public static String getk(int x, int y) {
            return x + " " + y;
        }
        
    
        public static String countLuck(List<String> matrix, int k) {
        // Write your code here
        // BFS, count choices.
            int[] dx = {-1, 0, 0, 1};
            int[] dy = {0, 1, -1, 0};
            Queue<Node> todo = new LinkedList<>();
            int x = 0;
            int y = 0;
            int n = matrix.size();
            int m = matrix.get(0).length();
            Set<String> dots = new HashSet<>();
            int goalx = 0;
            int goaly = 0;
            for (int j = 0; j < n; j++) {
                String s = matrix.get(j);
                for (int i = 0; i < m; i++) {
                    char c = s.charAt(i);
                    if (c == 'M') {
                        x = i;
                        y = j;
                    }
                    if (c == '.' || c == '*') {
                        dots.add(getk(i, j));
                    }
                    if (c == '*') {
                        goalx = i;
                        goaly = j;
                    }
                }
            }
            Set<String> seen = new HashSet<>();
            todo.add(new Node(x, y, 0));
            System.err.println("dots:" + dots);
            while (true) {
                Node here = todo.remove();
                seen.add(getk(here.x, here.y));
                // count paths.
                x = here.x;
                y = here.y;
                if (x == goalx && y == goaly) {
                    if (here.choices == k) {
                        return "Impressed";
                    };
                    return "Oops!";
                }
                int count = 0;
                List<Node> addme = new ArrayList<>();
                for (int q = 0; q < 4; q++) {
                    int nx = x + dx[q];
                    int ny = y + dy[q];
                    String key = getk(nx, ny);
                    if (! seen.contains(key) && dots.contains(key)) {
                        count++;
                        addme.add(new Node(nx, ny, 0));
                    }
                }
                int bump = (count > 1)? 1 : 0;
                here.choices += bump;
                for (Node node : addme) {
                    node.choices = here.choices;
                }
                todo.addAll(addme);
            }
        }
    }
    
    public class Solution {
        public static void main(String[] args) throws IOException {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
    
            int t = Integer.parseInt(bufferedReader.readLine().trim());
    
            IntStream.range(0, t).forEach(tItr -> {
                try {
                    String[] firstMultipleInput = bufferedReader.readLine().replaceAll("\\s+$", "").split(" ");
    
                    int n = Integer.parseInt(firstMultipleInput[0]);
    
                    int m = Integer.parseInt(firstMultipleInput[1]);
    
                    List<String> matrix = IntStream.range(0, n).mapToObj(i -> {
                        try {
                            return bufferedReader.readLine();
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                    })
                        .collect(toList());
    
                    int k = Integer.parseInt(bufferedReader.readLine().trim());
    
                    String result = Result.countLuck(matrix, k);
    
                    bufferedWriter.write(result);
                    bufferedWriter.newLine();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });
    
            bufferedReader.close();
            bufferedWriter.close();
        }
    }