문제 번호
14502번: 연구소
인체에 치명적인 바이러스를 연구하던 연구소에서 바이러스가 유출되었다. 다행히 바이러스는 아직 퍼지지 않았고, 바이러스의 확산을 막기 위해서 연구소에 벽을 세우려고 한다. 연구소는 크
www.acmicpc.net
알고리즘 분류
그래프 이론, 그래프 탐색, 브루트포스, 너비 우선 탐색
문제 풀이
브루트포스와 그래프 탐색을 모두 이용해야 하는 문제이다.
우선 브루트포스 알고리즘을 사용하여 주어지는 지도에 벽3개를 세울 수 있는 경우를 모두 다 조사해야한다.
function solution(y, x) {
if (cnt === 0) {
return count();
}
for (let i = y; i <= N; i++) {
for (let j = x; j <= M; j++) {
if (map[i][j] === 0) {
cnt--;
map[i][j] = 1
solution(y, x);
cnt++;
map[i][j] = 0;
}
}
}
}
그 다음 주어진 연구소 배열을 map2라는 배열에 옮겨담는다. map2 배열을 탐색하면서 바이러스('2')가 발견될때마다 BFS를 실행한다. 그렇게 (N, M)까지 모든 탐색과 BFS를 마치면 MAP2 를 다시 탐색하면서 안전지역의 갯수를 새어준다.
function count() {
// for(let i=1; i<=N; i++){
// for(let j=1; j<=M; j++){
// map2[i][j] = map[i][j];
// }
// }
map2 = map.map(v => v.slice());
let visited = new Array(10);
for (let i = 0; i < 10; i++) {
visited[i] = new Array(10).fill(false);
}
for (let i = 1; i <= N; i++) {
for (let j = 1; j <= M; j++) {
if (map2[i][j] === 2) {
BFS(i, j, visited);
}
}
}
let safe = 0;
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (map2[i][j] === 0)
safe++;
}
}
if (safe > max) {
max = safe;
}
}
BFS
function BFS(y, x, visited) {
let queue = [];
queue.push([y, x]);
visited[y][x] = true;
while (queue.length > 0) {
let xy = queue.shift();
let cy = xy[0];
let cx = xy[1];
for (let next = 0; next < 4; next++) {
let nextY = cy + dxy[next][0];
let nextX = cx + dxy[next][1];
if (!visited[nextY][nextX] && map2[nextY][nextX] === 0) {
queue.push([nextY, nextX]);
visited[nextY][nextX] = true;
map2[nextY][nextX] = 2;
}
}
}
}
전체코드
//let tt = 0;
const fs = require('fs');
const input = fs.readFileSync('연구소/input.txt').toString().split('\n');
const NM = input.shift().split(' ');
const N = Number(NM.shift());
const M = Number(NM.shift());
let dxy = [[-1, 0], [1, 0], [0, -1], [0, 1]];
let cnt = 3;
let max = 0;
let map = new Array(10);
for (let i = 0; i < 10; i++) {
map[i] = new Array(10);
}
let map2 = new Array(10);
for (let i = 0; i < 10; i++) {
map2[i] = new Array(10);
}
for (let i = 1; i <= N; i++) {
let temp = input.shift().split(' ');
for (let j = 1; j <= M; j++) {
map[i][j] = Number(temp[j - 1]);
}
}
function BFS(y, x, visited) {
let queue = [];
queue.push([y, x]);
visited[y][x] = true;
while (queue.length > 0) {
let xy = queue.shift();
let cy = xy[0];
let cx = xy[1];
for (let next = 0; next < 4; next++) {
let nextY = cy + dxy[next][0];
let nextX = cx + dxy[next][1];
if (!visited[nextY][nextX] && map2[nextY][nextX] === 0) {
queue.push([nextY, nextX]);
visited[nextY][nextX] = true;
map2[nextY][nextX] = 2;
}
}
}
}
function count() {
// for(let i=1; i<=N; i++){
// for(let j=1; j<=M; j++){
// map2[i][j] = map[i][j];
// }
// }
map2 = map.map(v => v.slice());
let visited = new Array(10);
for (let i = 0; i < 10; i++) {
visited[i] = new Array(10).fill(false);
}
for (let i = 1; i <= N; i++) {
for (let j = 1; j <= M; j++) {
if (map2[i][j] === 2) {
BFS(i, j, visited);
}
}
}
let safe = 0;
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (map2[i][j] === 0)
safe++;
}
}
if (safe > max) {
max = safe;
}
}
function solution(y, x) {
if (cnt === 0) {
return count();
}
for (let i = y; i <= N; i++) {
for (let j = x; j <= M; j++) {
if (map[i][j] === 0) {
cnt--;
map[i][j] = 1
solution(y, x);
cnt++;
map[i][j] = 0;
}
}
}
}
solution(1, 1)
console.log(max);
특이사항
문제가 어렵진 않았으나 오타를 못봐서 지ㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣㅣ이니ㅣㅣㅣㅣㅣㅣㅣㅣㅣ짜 오래걸렸다.
항상 집중해서 문제를 풀고 변수명을 쉽고, 알아보기 쉽게, 가독성 좋게 쓰자..........................................
분명 꼼꼼하게 50번도 넘게 봤는데 안보였다...
2차원 배열은 let arr2 = arr1.map(x => x.slice()) 와 같은 형태로 복사 할 수 있다.
'Algorithm > BaeKJoon' 카테고리의 다른 글
[JS][백준]3190_뱀 (0) | 2021.09.10 |
---|---|
[JS][백준]14503_로봇 청소기 (0) | 2021.09.09 |
[JS][백준]21608_상어 초등학교 (0) | 2021.09.09 |
[JS][백준]20055_컨베이어 벨트 위의 로봇 (0) | 2021.09.09 |
[JS][백준]11650_좌표 정렬하기 (1) | 2021.08.24 |