πŸ’‘λ¬Έμ œ 뢄석 μš”μ•½

πŸ’‘μ•Œκ³ λ¦¬μ¦˜ 섀계

πŸ’‘μ½”λ“œ

const fs = require('fs');
const path = require('path');

const input = fs.readFileSync(path.join(__dirname, 'input.txt')).toString().trim().split('\\n')

const N = parseInt(input[0], 10); // 첫 번째 쀄은 μ§€λ„μ˜ 크기 N
const map = input.slice(1).map((line) => line.split('').map(Number)); // 2차원 λ°°μ—΄λ‘œ λ³€ν™˜

function solution(N, map) {
  const dx = [-1, 1, 0, 0]; // 상, ν•˜, 쒌, 우
  const dy = [0, 0, -1, 1];

  const visited = Array.from({ length: N }, () => Array(N).fill(false)); // λ°©λ¬Έ λ°°μ—΄
  const complexes = []; // 단지별 μ§‘μ˜ 수λ₯Ό μ €μž₯ν•  λ°°μ—΄

  // DFS ν•¨μˆ˜
  const dfs = (x, y) => {
    let count = 1; // 집 ν•˜λ‚˜λ₯Ό λ°œκ²¬ν–ˆμœΌλ―€λ‘œ 초기 κ°’ 1
    visited[x][y] = true;

    // μƒν•˜μ’Œμš°λ‘œ 탐색
    for (let i = 0; i < 4; i++) {
      const nx = x + dx[i];
      const ny = y + dy[i];

      // μ§€λ„μ˜ λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜μ§€ μ•Šλ„λ‘
      if (nx >= 0 && ny >= 0 && nx < N && ny < N) {

        // λ°©λ¬Έν•˜μ§€ μ•Šμ•˜κ³ , 집이 μžˆμ„ 경우
        if (!visited[nx][ny] && map[nx][ny] === 1) {

          // μž¬κ·€μ μœΌλ‘œ νƒμƒ‰ν•˜λ©΄μ„œ μ§‘μ˜ 수λ₯Ό λ”ν•΄μ€Œ
          count += dfs(nx, ny);
        }
      }
    }

    return count; // ν•΄λ‹Ή λ‹¨μ§€μ˜ 총 집 수 λ°˜ν™˜
  };

  // 전체 맡 탐색
  for (let i = 0; i < N; i++) {

    for (let j = 0; j < N; j++) {

      // 집이 μžˆλŠ” μœ„μΉ˜μ—μ„œ DFS μ‹œμž‘
      if (map[i][j] === 1 && !visited[i][j]) {
        const complexSize = dfs(i, j);

        complexes.push(complexSize); // 단지 크기λ₯Ό μ €μž₯
      }
    }
  }

  complexes.sort((a, b) => a - b); // μ˜€λ¦„μ°¨μˆœ μ •λ ¬

  console.log(complexes.length); // 총 단지 수 좜λ ₯
  complexes.forEach((size) => console.log(size)); // 각 λ‹¨μ§€μ˜ 집 수 좜λ ₯
}

solution(N, map);

πŸ’‘μ‹œκ°„λ³΅μž‘λ„