From b2c3635232b48b287a2edd6d88d2ea3e3946c4bf Mon Sep 17 00:00:00 2001 From: JiHo00 <110150963+jihostudy@users.noreply.github.com> Date: Mon, 22 Jul 2024 05:42:50 +0900 Subject: [PATCH] Day21 Jiho 2Q --- ...70\353\266\231\354\235\264\352\270\260.js" | 9 +++ ...60\353\206\215\353\260\260\354\266\224.js" | 61 +++++++++++++++++ "Jiho/Day21/\353\260\261\354\244\200_2178.js" | 68 +++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 "Jiho/Day21/\353\260\261\354\244\200_1012_\354\234\240\352\270\260\353\206\215\353\260\260\354\266\224.js" create mode 100644 "Jiho/Day21/\353\260\261\354\244\200_2178.js" diff --git "a/Jiho/Day20/\353\260\261\354\244\200_BFS_\353\213\250\354\247\200\353\262\210\355\230\270\353\266\231\354\235\264\352\270\260.js" "b/Jiho/Day20/\353\260\261\354\244\200_BFS_\353\213\250\354\247\200\353\262\210\355\230\270\353\266\231\354\235\264\352\270\260.js" index e44832d..b336d55 100644 --- "a/Jiho/Day20/\353\260\261\354\244\200_BFS_\353\213\250\354\247\200\353\262\210\355\230\270\353\266\231\354\235\264\352\270\260.js" +++ "b/Jiho/Day20/\353\260\261\354\244\200_BFS_\353\213\250\354\247\200\353\262\210\355\230\270\353\266\231\354\235\264\352\270\260.js" @@ -55,3 +55,12 @@ function bfs(x, y) { console.log(answer.length); answer.sort((a, b) => a - b); answer.forEach((item) => console.log(item)); + +/* +교훈 +1. 필요하지 않은 경우의 수에 대해서는 BFS할 필요가 없다. +-> 검증이 필요한 곳에서만 BFS를 쪼개서 할 수 있다. +2. 2차원 배열 bfs (정형화된 패턴) +dx dy로 방향 배열을 선언하고, +nrow, ncol을 만드는 식으로 작성 + diff --git "a/Jiho/Day21/\353\260\261\354\244\200_1012_\354\234\240\352\270\260\353\206\215\353\260\260\354\266\224.js" "b/Jiho/Day21/\353\260\261\354\244\200_1012_\354\234\240\352\270\260\353\206\215\353\260\260\354\266\224.js" new file mode 100644 index 0000000..44babdf --- /dev/null +++ "b/Jiho/Day21/\353\260\261\354\244\200_1012_\354\234\240\352\270\260\353\206\215\353\260\260\354\266\224.js" @@ -0,0 +1,61 @@ +const fs = require("fs"); +const input = fs + .readFileSync(process.platform === "linux" ? "/dev/stdin" : "../input.txt") + .toString() + .trim() + .split("\n"); +const TESTCASE = parseInt(input.shift()); + +const BFS_SearchConnected = (startRow, startCol, N, M, visited, vegi) => { + // # 방향 + const dr = [0, 1, 0, -1]; + const dc = [1, 0, -1, 0]; + + const queue = [[startRow, startCol]]; + visited[startRow][startCol] = true; + + while (queue.length) { + // console.log("Here"); + // console.log(queue.shift()); + const [row, col] = queue.shift(); + for (let i = 0; i < 4; i++) { + const [nrow, ncol] = [row + dr[i], col + dc[i]]; + if ( + nrow >= 0 && + nrow < N && + ncol >= 0 && + ncol < M && + !visited[nrow][ncol] && + vegi[nrow][ncol] === 1 + ) { + visited[nrow][ncol] = true; + queue.push([nrow, ncol]); + } + } + } +}; + +// 각각의 TestCase +for (let tc = 0; tc < TESTCASE; tc++) { + // # 입력 처리 + const [M, N, K] = input.shift()?.split(" ").map(Number); + const vegi = Array.from(new Array(N), () => new Array(M).fill(0)); + + for (let i = 0; i < K; i++) { + const [inputCol, inputRow] = input.shift()?.trim().split(" ").map(Number); + vegi[inputRow][inputCol] = 1; + } + // # 방문 처리 + const visited = Array.from(new Array(N), () => new Array(M).fill(false)); + + let answer = 0; + for (let row = 0; row < N; row++) { + for (let col = 0; col < M; col++) { + if (!visited[row][col] && vegi[row][col] === 1) { + answer += 1; + BFS_SearchConnected(row, col, N, M, visited, vegi); + } + } + } + console.log(answer); +} diff --git "a/Jiho/Day21/\353\260\261\354\244\200_2178.js" "b/Jiho/Day21/\353\260\261\354\244\200_2178.js" new file mode 100644 index 0000000..c05bf0c --- /dev/null +++ "b/Jiho/Day21/\353\260\261\354\244\200_2178.js" @@ -0,0 +1,68 @@ +const fs = require("fs"); +const input = fs + .readFileSync(process.platform === "linux" ? "/dev/stdin" : "../input.txt") + .toString() + .trim() + .split("\n"); + +const [N, M] = input.shift().split(" ").map(Number); +const arr = input.map((subarr) => subarr.trim().split("")); +// # 방향 변수 +const dr = [0, 1, 0, -1]; +const dc = [1, 0, -1, 0]; + +const queue = [[0, 0, 1]]; +let visited = Array.from(new Array(N), () => new Array(M).fill(false)); +visited[0][0] = true; +let min = -1; + +while (queue.length) { + const [row, col, cnt] = queue.shift(); + console.log(row, col, cnt); + // # 도착 지점 도달 + if (row === N - 1 && col === M - 1) { + min = min === -1 ? cnt : Math.min(min, cnt); + } + // # 도착 지점 이동중 + else { + let i = 0; + for (i; i < 4; i++) { + const [nrow, ncol] = [row + dr[i], col + dc[i]]; + if ( + nrow >= 0 && + nrow < N && + ncol >= 0 && + ncol < M && + arr[nrow][ncol] === "1" + ) { + queue.push([nrow, ncol, cnt + 1]); + visited[nrow][ncol] = true; + } + } + } +} +console.log(min); + +/* +✍️교훈 +처음에는 visited[row][col] = true를 queue에서 꺼냈을 때 했었는데, +Time out Error가 발생함 + +최적화 필요!! +이때, visited의 뜻 : 해당 점에서 시작하는 모든 경우의 수를 고려했음. +그러면, queue에서 뺐을때 넣는게 아니라, 큐에 넣을때 visited를 바꾸면 최적화 가능 +문제는 다음과 같은 상황 + +1111 [3][3]의 1은 위에서 오는 경로랑 아래로 쭉 돌아서 오는 경로 2가지가 존재. +1001 이렇게, 모든 경우의 수를 판단해서 최소의 값을 구해야 하는게 아닌가? 라는 생각이 들었음 +1001 But, BFS의 개념을 이해하면 된다. +1011 BFS는 같은 LEVEL (거리)를 먼저 판단한다. +1110 같은 점에 서로 다른 시점에 들어왔다는 것은 이미 그 점으로의 최소 길이 아님. + 즉, 먼저 오는 방향이 제일 짧은 길이일 것임 (방향은 다를 수 있지만, 같은 LEVEL에 도달하는 방향이면 어차피 정답은 같다) + +추가 +만약에, 모든 경로를 구해야하는 거라면 visited = true는 queue에서 꺼냇을 때 하는게 맞다. + + +따라서, 최적의 상황은 qeuue에 넣을때 하는것. +*/