티스토리 뷰
https://www.acmicpc.net/problem/10026
10026번: 적록색약
적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록)
www.acmicpc.net
핵심 아이디어
dfs 및 bfs 을 활용하여 상 하 좌 우 연속되는 RGB를 확인해 나갈 수 있다.
색약인 아닌 경우 연속되는지 확인하며 count를 구한다.
색약인 경우 "R"과 "G"인 경우 "RG"로 통일한 후 연속되는지 확인하며 count를 구한다.
DFS 로 풀이
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\n");
let n = Number(input[0]); // row의 개수
let graph = [];
for (let i = 1; i <= n; i++) {
graph.push(input[i].split(""));
}
// 상 하 좌 우
const position = [
[0, -1],
[0, 1],
[-1, 0],
[1, 0],
];
let visited = Array.from({ length: n }, () => Array(n).fill(false));
const isRangeOver = (x, y) => {
if (x < 0 || x >= n || y < 0 || y >= n) return false;
return true;
};
const dfs = ([x, y], color) => {
if (!isRangeOver(x, y) || visited[x][y] || graph[x][y] !== color) return;
visited[x][y] = true;
for (const [px, py] of position) {
dfs([x + px, y + py], color);
}
};
// 색약이 아닐때
let normalCnt = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (visited[i][j]) continue;
dfs([i, j], graph[i][j]);
normalCnt++;
}
}
// 색약일때
visited = Array.from({ length: n }, () => Array(n).fill(false));
graph = graph.map((v) => v.map((l) => (l == "R" || l == "G" ? "RG" : l)));
let RGWeaknessCnt = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (visited[i][j]) continue;
dfs([i, j], graph[i][j]);
RGWeaknessCnt++;
}
}
console.log(`${normalCnt} ${RGWeaknessCnt}`);
BFS 로 풀이
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\n");
class Queue {
constructor() {
this.items = {};
this.headIndex = 0;
this.tailIndex = 0;
}
enqueue(item) {
this.items[this.tailIndex] = item;
this.tailIndex++;
}
dequeue() {
const item = this.items[this.headIndex];
delete this.items[this.headIndex];
this.headIndex++;
return item;
}
peek() {
return this.items[this.headIndex];
}
getLength() {
return this.tailIndex - this.headIndex;
}
}
let n = Number(input[0]); // row의 개수
// 우 하 좌 상
const position = [
[1, 0],
[0, 1],
[-1, 0],
[0, -1],
];
let graph = [];
for (let i = 1; i <= n; i++) {
graph.push(input[i].split(""));
}
const isRangeOver = (x, y) => {
if (x < 0 || x >= n || y < 0 || y >= n) return false;
return true;
};
// 방문 확인
let visited = Array.from({ length: n }, () => Array(n).fill(false));
const bfs = (x, y) => {
const queue = new Queue();
queue.enqueue([x, y]);
while (queue.getLength()) {
const [cx, cy] = queue.dequeue();
for ([a, b] of position) {
const [nx, ny] = [cx + a, cy + b];
if (
isRangeOver(nx, ny) &&
!visited[nx][ny] &&
graph[cx][cy] == graph[nx][ny]
) {
visited[nx][ny] = true;
queue.enqueue([nx, ny]);
}
}
}
};
// 적록색약 아닌 경우
let normalCnt = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (!visited[i][j]) {
bfs(i, j);
normalCnt++;
}
}
}
// 적록색약인 경우
graph = graph.map((v) => v.map((l) => (l == "R" || l == "G" ? "RG" : l)));
visited = Array.from({ length: n }, () => Array(n).fill(false));
let RGWeaknessCnt = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (!visited[i][j]) {
bfs(i, j);
RGWeaknessCnt++;
}
}
}
console.log(`${normalCnt} ${RGWeaknessCnt}`);
'Algorithm > 백준' 카테고리의 다른 글
[백준] 17219 - 비밀번호 찾기 (Javascript / node) (0) | 2023.11.06 |
---|---|
[백준] 11403 - 경로 찾기 (Javascript / node) (0) | 2023.11.05 |
[백준] 1074 - Z (Javascript / node) (0) | 2023.11.03 |
[백준] 4963 섬의 개수 Javascript (0) | 2023.10.16 |
[백준] 11724 연결 요소의 개수 Javascript (0) | 2023.10.15 |
공지사항
최근에 올라온 글