180

发布时间 2023-06-18 19:03:13作者: xxin111

通过回测法求出所有满足的区域,

  • 在回潮的同时记录其入口坐标,入口个数大于1则不符合要求;,

  • 入口个数等于1时,判断其区域大小;

  • 如果存在多个区域,且区域大小相同,则只需记录其大小; 其他情况则需要记录区域最大值和横纵坐标

关键代码:

public interface Runnable {
    public static void main(String[] args) {
        // 处理输入
        Scanner in = new Scanner(System.in);
        int m = in.nextInt();
        int n = in.nextInt();

        Character[][] matrix = new Character[m][n];
        in.nextLine();

        for (int i = 0; i < m; i++) {
            String[] strs = in.nextLine().split(" ");
            for (int j = 0; j < n; j++) {
                matrix[i][j] = strs[j].charAt(0);
            }
        }

        //最大的区域大小
        int max_area = 0;
        // 记录单入口区域的入口坐标,区域大小
        HashMap<String, Integer> zones = new HashMap<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 'O' && (i == 0 || j == 0 || i == m - 1 || j == n - 1)) {
                    //先假定当前可以为入口
                    int area = calc_area(copy(matrix), i, j, true);
                    if (area > 0) {
                        String key = i + " " + j;
                        zones.put(key, area);
                        if (area > max_area) {
                            max_area = area;
                        }
                    }

                }
            }
        }

        //输出
        String max_entrace = "";
        for (Map.Entry<String, Integer> e : zones.entrySet()) {
            if (e.getValue() == max_area) {
                if (max_entrace.isEmpty()) {
                    max_entrace = e.getKey();
                } else {
                    max_entrace = "more";
                    break;
                }
            }
        }

        if (max_area == 0) {
            System.out.println("NULL");
        } else if (max_entrace == "more") {
            System.out.println(max_area);
        } else {
            System.out.println(max_entrace + " " + max_area);
        }

    }

    public static Character[][] copy(Character[][] a) {
        int m = a.length;
        int n = a[0].length;
        Character[][] matrix = new Character[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = a[i][j];
            }
        }
        return matrix;
    }
    // i, j为入口的区域大小,
    public static int calc_area(Character[][] matrix, int i, int j, boolean flag) {
        if (!flag) {
            // 遍历到边界时,说明有其他入口,则不是单入口
            if (i == 0 || i == matrix.length - 1 || j == 0 || j == matrix[0].length - 1) {
                return 0;
            }
        }

        matrix[i][j] = 'X';
        // 记录区域大小
        int count = 1;

        int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        for (int[] direction : directions) {
            int newX = i + direction[0], newY = j + direction[1];
            if (newX >= 0 && newX < matrix.length && newY >= 0 && newY < matrix[0].length
                && matrix[newX][newY] == 'O') {
                int count1 = calc_area(matrix, newX, newY, false);
                if (count1 == 0) {
                    return 0;
                }
                count += count1;
            }
        }
        return count;
    }