www.acmicpc.net/problem/2667
2667번: 단지번호붙이기
<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집들의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다.
www.acmicpc.net
핵심 아이디어
dfs/bfs 방식으로 풀 수 있는 문제이고 입력 크기가 작기에 dfs로 풀어도 상관없다.
dfs는 재귀적으로 더이상 탐색할 노드가 없을 때 재귀를 탈출하게 되는데,
그 점을 이용하여 재귀를 탈출할때마다 방문했던 수를 배열에 추가해주고 출력하면된다.
'use strict';
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const solution = function (input) {
const n = parseInt(input.shift());
const direction = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1],
];
const visited = [];
const housePoint = [];
const board = input.map((string, rowIdx) => {
const row = Array.from(string).map((str) => parseInt(str));
row.forEach((elem, colIdx) => {
if (elem === 1) {
housePoint.push([rowIdx, colIdx]);
}
});
visited.push(new Array(n + 1).fill(0));
return row;
});
const checkValidPoint = (x, y) => {
if ((x >= 0) & (y >= 0) && x < n && y < n) {
return true;
}
return false;
};
const dfs = (x, y) => {
for (const [a, b] of direction) {
if (checkValidPoint(x + a, y + b) && !visited[x + a][y + b]) {
if (board[x + a][y + b] === 1) {
visited[x + a][y + b] = 1;
cnt++;
dfs(x + a, y + b);
}
}
}
};
const ans = [];
let cnt = 0;
while (housePoint.length > 0) {
const [x, y] = housePoint.shift();
cnt = 0;
if (!visited[x][y]) {
visited[x][y] = 1;
cnt++;
dfs(x, y);
}
if (cnt > 0) ans.push(cnt);
}
ans.sort((a, b) => a - b);
console.log(ans.length);
if (ans.length > 0) {
console.log(ans.join('\n'));
}
};
const input = [];
rl.on('line', function (line) {
input.push(line);
}).on('close', function () {
solution(input);
process.exit();
});