https://www.acmicpc.net/problem/2583
2583번: 영역 구하기
첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오
www.acmicpc.net
📌 작성한 코드
// 2583
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "Beakjoon/Silver/test.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\n");
const [M, N, K] = input.shift().split(" ").map(Number);
const map = Array.from({ length: N }, () => new Array(M).fill(false));
for (let i = 0; i < K; i++) {
const [x1, y1, x2, y2] = input.shift().split(" ").map(Number);
for (let j = x1; j < x2; j++) {
for (let k = y1; k < y2; k++) {
map[j][k] = true;
}
}
}
const dx = [1, -1, 0, 0];
const dy = [0, 0, 1, -1];
const dfs = (a, b) => {
let count = 0;
const stack = [];
stack.push([a, b]);
map[a][b] = true;
while (stack.length) {
const [x, y] = stack.pop();
count++;
for (let i = 0; i < 4; i++) {
const nx = x + dx[i];
const ny = y + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
if (!map[nx][ny]) {
stack.push([nx, ny]);
map[nx][ny] = true;
}
}
}
return count;
};
const answer = [];
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (!map[i][j]) {
answer.push(dfs(i, j));
}
}
}
console.log(answer.length);
console.log(answer.sort((a, b) => a - b).join(" "));
📌 풀이
블럭의 범위를 방문처리 해준 뒤 방문하지 않은 부분에 대해서 dfs를 돌며 영역의 범위를 구하면 되는 문제이다.
1. 영역의 시작, 끝 좌표를 입력받고 해당 범위만큼 방문처리 해준다.
for (let i = 0; i < K; i++) {
const [x1, y1, x2, y2] = input.shift().split(" ").map(Number);
for (let j = x1; j < x2; j++) {
for (let k = y1; k < y2; k++) {
map[j][k] = true;
}
}
}
2. dfs를 통해 방문하지 않은 영역 방문하고, 영역의 개수를 세어준다.
const dfs = (a, b) => {
let count = 0;
const stack = [];
stack.push([a, b]);
map[a][b] = true;
while (stack.length) {
const [x, y] = stack.pop();
count++; // stack에서 꺼내면서 블럭의 개수 증가시키기
for (let i = 0; i < 4; i++) {
const nx = x + dx[i];
const ny = y + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
if (!map[nx][ny]) {
stack.push([nx, ny]);
map[nx][ny] = true;
}
}
}
return count; // 블럭의 개수 반환
};
3. 전체 영역을 반복문을 돌면서 방문되지 않은 위치에서 dfs 돌면서 영역의 개수와 범위를 구해준다.
const answer = [];
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (!map[i][j]) {
answer.push(dfs(i, j));
}
}
}
console.log(answer.length);
console.log(answer.sort((a, b) => a - b).join(" "));
✅ 성공

'알고리즘 > 백준' 카테고리의 다른 글
| [JavaScript/BFS] 백준 골드 5 : 13549 - 숨바꼭질 3 (1) | 2024.01.18 |
|---|---|
| [JavaScript/BFS] 백준 골드 5 : 6593 - 상범 빌딩 (0) | 2024.01.16 |
| [JavaScript/BFS] 백준 실버 1 : 7562 - 나이트의 이동 (0) | 2024.01.12 |
| [JavaScript/DFS] 백준 골드 5 : 10026 - 적록색약 (2) | 2024.01.11 |
| [JavaScript/BFS] 백준 골드 5 : 7576 - 토마토 (0) | 2024.01.10 |