城堡问题.java 3.1 KB
Newer Older
qq_36480062's avatar
c  
qq_36480062 已提交
1 2 3 4 5 6 7
package DFS.floodfill;

import java.util.ArrayDeque;
import java.util.Scanner;

/**
 * https://blog.csdn.net/qq_30277239/article/details/104670312
qq_36480062's avatar
c  
qq_36480062 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 * 请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大。
 * 城堡被分割成 m∗n个方格区域,每个方格区域可以有0~4面墙。
 * 输入格式
 * 第一行包含两个整数 m 和 n,分别表示城堡南北方向的长度和东西方向的长度。
 * 接下来 m 行,每行包含 n 个整数,每个整数都表示平面图对应位置的方块的墙的特征。
 * 每个方块中墙的特征由数字 P 来描述,我们用1表示西墙,2表示北墙,4表示东墙,8表示南墙,P 为该方块包含墙的数字之和。
 * 例如,如果一个方块的 P 为3,则 3 = 1 + 2,该方块包含西墙和北墙。
 * 城堡的内墙被计算两次,方块(1,1)的南墙同时也是方块(2,1)的北墙。
 * 输入的数据保证城堡至少有两个房间。
 * 输出格式
 * 共两行,第一行输出房间总数,第二行输出最大房间的面积(方块数)。
 * 数据范围
 * 1≤m,n≤50,
 * 0≤P≤15
 * 输入样例:
 * 4 7
 * 11 6 11 6 3 10 6
 * 7 9 6 13 5 15 5
 * 1 10 12 7 13 7 5
 * 13 11 10 8 10 12 13
 * 输出样例:
 * 5
 * 9
qq_36480062's avatar
c  
qq_36480062 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
 * 显然寻找有多少个四联通块
 * 并找出最大连通块有多少个
 */
public class 城堡问题 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                g[i][j] = sc.nextInt();
            }
        }
        int cnt = 0, area = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!vis[i][j]) {
                    area = Math.max(bfs(i, j), area);
                    cnt++;
                }
            }
        }
        System.out.println(cnt);
        System.out.println(area);
    }

    private static int bfs(int x, int y) {
        int area = 0;
        q.clear();
        q.add(x * m + y);
        while (!q.isEmpty()) {
            int p = q.poll();
            x = p / m;
            y = p % m;
            area++;
            vis[x][y] = true;
            for (int i = 0; i < 4; i++) {
                int a = x + dir[i][0], b = y + dir[i][1];
                if (a < 0 || a >= n || b < 0 || b >= m || vis[a][b]) continue;
                if ((g[x][y] >> i & 1) == 1) continue;
                q.add(a * m + b);
            }
        }
        return area;
    }

    static void dfs(int x, int y) {
        ans++;
        vis[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int a = x + dir[i][0], b = y + dir[i][1];
            if (a < 0 || a >= n || b < 0 || b >= m || vis[a][b]) continue;
            if ((g[x][y] >> i & 1) == 1) continue;
            dfs(a, b);
        }
    }

    static int[][] dir = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    static int[][] g = new int[51][51];
    static boolean[][] vis = new boolean[51][51];
    static ArrayDeque<Integer> q = new ArrayDeque<Integer>();
    static int n, m, ans;
}