[白俊]#16932制作模様



質問する


N×M人の並びで形を見つけたいです.配列された各グリッドには0と1の1つが含まれています.2つの格子がエッジを共有する場合、隣接する2つの格子があるそうです.
隣接するセル間で1が接続されている場合、各接続要素をシェイプと呼びます.形状の大きさは、形状に含まれる1の個数です.
形状の最大サイズを求め、配列内のセルの数を変えることで作成できます.

入力


最初の行は配列のサイズNとMを与える.2行目から、N行には配列内の数字が与えられる.

しゅつりょく


最初の行で数を変更し、作成できるシェイプの最大サイズを出力します.

制限

  • 2 ≤ N, M ≤ 1,000
  • 0と1の個数は1つ以上です.
  • 入力例1

    3 3
    0 1 1
    0 0 1
    0 1 0

    サンプル出力1

    5

    入力例2

    5 4
    1 1 0 0
    1 0 1 0
    1 0 1 0
    0 1 1 0
    1 0 0 1

    サンプル出力2

    10

    入力例3

    3 4
    0 1 0 1
    0 0 0 1
    1 1 0 1

    サンプル出力3

    6

    に答える


    この問題はbfs(幅優先探索)アルゴリズムとDFS(深さ優先探索)で解決できる.
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Main {
        static int N;
        static int M;
        static int[][] map;
        static boolean[][] visited;
        static int max = 0;
        static int[] size = new int[1000000];
        static boolean[] flag = new boolean[1000000];
        static int[] dx = {-1, 1, 0, 0};
        static int[] dy = {0, 0, -1, 1};
    
        public static void main(String[] args) throws Exception{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] input = br.readLine().split(" ");
            N = Integer.parseInt(input[0]);
            M = Integer.parseInt(input[1]);
            map = new int[N][M];
            visited = new boolean[N][M];
            Queue<Pair> one = new LinkedList<>();
            Queue<Pair> zero = new LinkedList<>();
    
            for(int i=0; i<N; i++) {
                input = br.readLine().split(" ");
                for(int j=0; j<M; j++) {
                    map[i][j] = Integer.parseInt(input[j]);
                    if(map[i][j]==0)
                        zero.add(new Pair(i, j));
                    else
                        one.add(new Pair(i, j));
                }
            }
    
            int num = 1;
            while(!one.isEmpty()) {
                Pair temp = one.poll();
                if(!visited[temp.x][temp.y]) {
                    bfs(temp.x, temp.y, num);
                    num++;
                }
            }
    
            while(!zero.isEmpty()) {
                Pair temp = zero.poll();
    
                dfs(temp.x, temp.y, 0, 1);
            }
    
            System.out.println(max);
        }
    
        public static void dfs(int x, int y, int idx, int result) {
            if(idx==4) {
                max = Math.max(max, result);
                return;
            }
    
            int nx = x+dx[idx];
            int ny = y+dy[idx];
    
            if (nx<0 || ny<0 || nx>=N || ny>=M || map[nx][ny]==0 || flag[map[nx][ny]-1]) {
                dfs(x, y, idx+1, result);
                return;
            }
    
            flag[map[nx][ny]-1] = true;
            dfs(x, y, idx+1, result+size[map[nx][ny]]);
            flag[map[nx][ny]-1] = false;
        }
    
        public static void bfs(int x, int y, int num) {
            Queue<Pair> queue = new LinkedList<>();
            map[x][y] = num;
            visited[x][y] = true;
            int cnt = 1;
            queue.add(new Pair(x, y));
    
            while(!queue.isEmpty()) {
                Pair temp = queue.poll();
    
                for(int i=0; i<4; i++) {
                    int nx = temp.x+dx[i];
                    int ny = temp.y+dy[i];
    
                    if(nx<0 || nx>=N || ny<0 || ny>=M || visited[nx][ny] || map[nx][ny]==0) continue;
    
                    map[nx][ny] = num;
                    visited[nx][ny] = true;
                    queue.add(new Pair(nx, ny));
                    cnt++;
                }
            }
    
            size[num] = cnt;
        }
    
        public static class Pair {
            int x;
            int y;
    
            public Pair(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
    }