diff --git a/jueun/week16/1654.js b/jueun/week16/1654.js new file mode 100644 index 0000000..fb61e3c --- /dev/null +++ b/jueun/week16/1654.js @@ -0,0 +1,51 @@ +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n"); + +const input = ["4 11", "802", "743", "457", "539"]; +// const input = ["1 1", "5"]; + +const [[K, N], lanLines] = [ + input[0].split(" ").map(BigInt), + input.slice(1).map(BigInt), +]; + +const solution = (lanLines, n) => { + let mid = bigIntMax(...lanLines); + let low = 0n, + high = mid; + let newMid; + let maxLength = 0n; + let nowCount; + + while (true) { + nowCount = getNowCount(lanLines, mid); + + if (nowCount < n) { + high = mid; + } else if (nowCount >= n) { + low = mid; + maxLength = bigIntMax(maxLength, mid); + } + + newMid = BigInt(BigInt(low) + BigInt(high)) / 2n; + + if (newMid === mid || newMid === low || newMid === high) break; + mid = newMid; + } + + return maxLength; +}; + +const bigIntMin = (...args) => + args.reduce((prev, cur) => (cur < prev ? cur : prev)); + +const bigIntMax = (...args) => + args.reduce((prev, cur) => (cur > prev ? cur : prev)); + +const getNowCount = (lanLines, mid) => + lanLines.reduce((prev, cur) => prev + cur / mid, 0n); + +console.log(String(solution(lanLines, N))); diff --git a/jueun/week16/19637.js b/jueun/week16/19637.js new file mode 100644 index 0000000..2c614b9 --- /dev/null +++ b/jueun/week16/19637.js @@ -0,0 +1,54 @@ +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n"); + +const input = [ + "3 8", + "WEAK 10000", + "NORMAL 100000", + "STRONG 1000000", + "0", + "9999", + "10000", + "10001", + "50000", + "100000", + "500000", + "1000000", +]; + +const [N, M] = input[0].split(" ").map(Number); +const [ranges, numbers] = [ + input + .slice(1, N + 1) + .map((el) => el.split(" ").map((e) => (isNaN(e) ? e : +e))), + input.slice(N + 1).map(Number), +]; + +const solution = (n, m, ranges, numbers) => { + let answer = ""; + for (let i = 0; i < m; i++) { + answer += ranges[findRangeIdx(numbers[i], n, ranges)][0] + "\n"; + } + return answer; +}; + +const findRangeIdx = (target, n, ranges) => { + let mid = 0, + low = 0, + high = n - 1; + while (low <= high) { + mid = Math.floor((low + high) / 2); + if (target <= ranges[mid][1]) { + high = mid - 1; + } else { + low = mid + 1; + } + } + if (target > ranges[mid][1]) return mid + 1; + else return mid; +}; + +console.log(solution(N, M, ranges, numbers)); diff --git a/jueun/week16/2512.js b/jueun/week16/2512.js new file mode 100644 index 0000000..1f9b9c8 --- /dev/null +++ b/jueun/week16/2512.js @@ -0,0 +1,46 @@ +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n") + +// const input = ["4", "120 110 140 150", "485"]; +const input = ["5", "70 80 30 40 100", "450"]; + +const [N, requests, M] = [ + +input[0], + input[1].split(" ").map(Number), + +input[2], +]; + +const solution = (requests, m) => { + let mid = Math.max(...requests); + let newMid; + let high = mid, + low = 0; + let sum, + maxSum = 0; + + while (true) { + sum = requests.reduce((prev, cur) => { + if (cur > mid) return prev + mid; + else return prev + cur; + }, 0); + + if (sum > m) { + high = mid; + } else if (sum < m) { + low = mid; + maxSum = Math.max(sum, maxSum); + } else { + break; + } + newMid = Math.floor((low + high) / 2); + if (newMid === mid) break; + else mid = newMid; + } + + return mid; +}; + +console.log(solution(requests, M)); diff --git a/jueun/week16/2805.js b/jueun/week16/2805.js new file mode 100644 index 0000000..a3229f2 --- /dev/null +++ b/jueun/week16/2805.js @@ -0,0 +1,46 @@ +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n") + +// const input = ["4 7", "20 15 10 17"]; +const input = ["5 20", "4 42 40 26 46"]; + +const [[N, M], trees] = [ + input[0].split(" ").map(Number), + input[1].split(" ").map(Number), +]; + +const solution = (trees, m) => { + const treeSum = trees.reduce((prev, cur) => prev + cur) - m; + let mid = Math.max(...trees); + let newMid; + let high = mid, + low = 0; + let sum, + maxSum = 0; + + while (true) { + sum = trees.reduce((prev, cur) => { + if (cur > mid) return prev + mid; + else return prev + cur; + }, 0); + + if (sum > treeSum) { + high = mid; + } else if (sum < treeSum) { + low = mid; + maxSum = Math.max(sum, maxSum); + } else { + break; + } + newMid = Math.floor((low + high) / 2); + if (newMid === mid) break; + else mid = newMid; + } + + return mid; +}; + +console.log(solution(trees, M)); diff --git a/jueun/week16/6236.js b/jueun/week16/6236.js new file mode 100644 index 0000000..7d39aaa --- /dev/null +++ b/jueun/week16/6236.js @@ -0,0 +1,49 @@ +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n"); + +const input = ["7 5", "100", "400", "300", "100", "500", "101", "400"]; + +const [[N, M], moneys] = [ + input[0].split(" ").map(Number), + input.slice(1).map(Number), +]; + +const solution = (n, m, moneys) => { + let minMoney = moneys.reduce((prev, cur) => prev + cur); + let low = Math.max(...moneys), + high = minMoney; + let mid = high; + let count; + + while (low <= high) { + count = getCount(n, mid, moneys); + + if (count > m) { + low = mid + 1; + } else { + minMoney = mid; + high = mid - 1; + } + mid = Math.floor((low + high) / 2); + } + + return minMoney; +}; + +const getCount = (n, mid, moneys) => { + let count = 0, + remain = 0; + + for (let i = 0; i < n; i++) { + if (remain < moneys[i]) { + count++; + remain = mid - moneys[i]; + } else remain -= moneys[i]; + } + return count++; +}; + +console.log(solution(N, M, moneys)); diff --git a/jueun/week17/1012.js b/jueun/week17/1012.js new file mode 100644 index 0000000..b8a6def --- /dev/null +++ b/jueun/week17/1012.js @@ -0,0 +1,102 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1012.txt" + ) + .toString() + .split("\n"); + +// const input = [ +// "2", +// "10 8 17", +// "0 0", +// "1 0", +// "1 1", +// "4 2", +// "4 3", +// "4 5", +// "2 4", +// "3 4", +// "7 4", +// "8 4", +// "9 4", +// "7 5", +// "8 5", +// "9 5", +// "7 6", +// "8 6", +// "9 6", +// "10 10 1", +// "5 5", +// ]; + +// const input = ["1", "5 3 6", "0 2", "1 2", "2 2", "3 2", "4 2", "4 0"]; + +const T = +input[0]; + +/* +1. 배추밭 만들기 + makeField 함수 구현 + +2. visited 2차원 배열 만들기 + 모든 위치를 false로 초기화 한 후, dfs 실행할 때 방문한 노드는 true 할당하기 + +3. dfs 실행 +worms = 0으로 정하고, dfs 실행이 끝날 때마다 worms++ +for문 내에서 +visited에 방문하지 않은 노드가 있을 경우 그 노드로 dfs 실행 + +for문이 끝나면 return worms +*/ + +const makeField = (m, n, positions) => { + const field = new Array(m); + for (let i = 0; i < m; i++) field[i] = new Array(n).fill(0); + + positions.forEach((xy) => { + field[xy[0]][xy[1]] = 1; + }); + + return field; +}; + +const solution = (m, n, k, posOfCabbages) => { + let worms = 0; + + const cabbageField = makeField(m, n, posOfCabbages); + + const visited = new Array(m); + for (let i = 0; i < m; i++) visited[i] = new Array(n).fill(false); + + const dfs = (i, j) => { + visited[i][j] = true; + if (cabbageField[i - 1]?.[j] === 1 && !visited[i - 1]?.[j]) dfs(i - 1, j); + if (cabbageField[i + 1]?.[j] === 1 && !visited[i + 1]?.[j]) dfs(i + 1, j); + if (cabbageField[i]?.[j - 1] === 1 && !visited[i]?.[j - 1]) dfs(i, j - 1); + if (cabbageField[i]?.[j + 1] === 1 && !visited[i]?.[j + 1]) dfs(i, j + 1); + + return; + }; + + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (cabbageField[i][j] === 1 && !visited[i][j]) { + dfs(i, j); + worms++; + } + } + } + + return worms; +}; + +let MNKIdx = 1; +for (let i = 0; i < T; i++) { + let [M, N, K] = input[MNKIdx].split(" ").map(Number); + let posOfCabbages = input + .slice(MNKIdx + 1, MNKIdx + K + 1) + .map((xy) => xy.split(" ").map(Number)); + MNKIdx += K + 1; + + console.log(solution(M, N, K, posOfCabbages)); +} diff --git a/jueun/week17/10552.js b/jueun/week17/10552.js new file mode 100644 index 0000000..3295fbd --- /dev/null +++ b/jueun/week17/10552.js @@ -0,0 +1,67 @@ +// 메모리 초과 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/10552.txt" + ) + .toString() + .split("\n") + .map((el) => el.split(" ").map(Number)); + +const [[N, M, P], ...channelPreference] = input; + +/* +0~2번 노인의 채널 선호도 + + favorite hate +0: 1 2 +1: 2 3 +2: 3 2 + +1. 인접 행렬 만들기 +- hate -> favorite 방향으로 간선 생성 +- 이미 어린 사람이 hate하는 채널이면 나이 많은 사람 간선은 생성 X + +2. dfs로 돌기 +- visited 배열에 방문 체크하기 +- dfs 한번 호출할 때마다 count++ +- 이미 방문한 노드에 재방문할 경우 return -1 + +*/ + +const solution = (m, first, channelPreference) => { + let count = 0; + const makeAdjMatrix = (m, channelPreference) => { + const matrix = new Array(m + 1); + for (let i = 0; i <= m; i++) matrix[i] = new Array(m + 1).fill(0); + const alreadyHate = new Array(m + 1).fill(false); + for (let [favorite, hate] of channelPreference) { + if (!alreadyHate[hate]) { + matrix[hate][favorite] = 1; + alreadyHate[hate] = true; + } + } + return matrix; + }; + + const adjMatrix = makeAdjMatrix(m, channelPreference); + + const visited = new Array(m + 1).fill(false); + const dfs = (node) => { + if (visited[node]) return -1; + visited[node] = true; + for (let i = 1; i <= m; i++) { + if (adjMatrix[node][i]) { + count++; + return dfs(i); + } + } + }; + + if (dfs(first) === -1) return -1; + + return count; +}; + +console.log(solution(M, P, channelPreference)); diff --git a/jueun/week17/10552_2.js b/jueun/week17/10552_2.js new file mode 100644 index 0000000..3a46c7b --- /dev/null +++ b/jueun/week17/10552_2.js @@ -0,0 +1,47 @@ +// 인접 행렬을 1차원 배열로 만듦 -> 통과 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/10552.txt" + ) + .toString() + .split("\n") + .map((el) => el.split(" ").map(Number)); + +const [[N, M, P], ...channelPreference] = input; + +const solution = (m, first, channelPreference) => { + let count = 0; + const makeAdjMatrix = (m, channelPreference) => { + const matrix = new Array(m + 1); + const alreadyHate = new Array(m + 1).fill(false); + for (let [favorite, hate] of channelPreference) { + if (!alreadyHate[hate]) { + matrix[hate] = favorite; + alreadyHate[hate] = true; + } + } + return matrix; + }; + + const adjMatrix = makeAdjMatrix(m, channelPreference); + + const visited = new Array(m + 1).fill(false); + const dfs = (node) => { + if (visited[node]) return -1; + visited[node] = true; + for (let i = 1; i <= m; i++) { + if (adjMatrix[node] === i) { + count++; + return dfs(i); + } + } + }; + + if (dfs(first) === -1) return -1; + + return count; +}; + +console.log(solution(M, P, channelPreference)); diff --git a/jueun/week17/11403.js b/jueun/week17/11403.js new file mode 100644 index 0000000..261ab89 --- /dev/null +++ b/jueun/week17/11403.js @@ -0,0 +1,51 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/11403.txt" + ) + .toString() + .split("\n"); + +const N = +input[0]; +const adjMatrix = input.slice(1).map((el) => el.split(" ").map(Number)); + +const solution = (n, adjMatrix) => { + let visited = new Array(n).fill(false); + const wayMatrix = new Array(n); + for (let i = 0; i < n; i++) wayMatrix[i] = new Array(n).fill(0); + + const dfs = (node, start) => { + for (let i = 0; i < adjMatrix[node].length; i++) { + if (adjMatrix[node][i] === 1 && !visited[i]) { + visited[i] = true; + wayMatrix[start][i] = 1; + dfs(i, start); + } + } + }; + + const makeWayMatrix = (n) => { + for (let i = 0; i < n; i++) { + visited = Array(n).fill(false); + dfs(i, i); + } + }; + + const matrix2String = (matrix) => { + let str = ""; + + matrix.forEach((arr) => { + str += arr.join(" "); + str += "\n"; + }); + + return str; + }; + + makeWayMatrix(n); + const matrixStr = matrix2String(wayMatrix); + + return matrixStr; +}; + +console.log(solution(N, adjMatrix)); diff --git a/jueun/week17/11724.js b/jueun/week17/11724.js new file mode 100644 index 0000000..8a0a127 --- /dev/null +++ b/jueun/week17/11724.js @@ -0,0 +1,72 @@ +/* +1. 인접 행렬 만들기 +adj[i][j]: 노드 i에서 노드 j로 가는 간선이 있으면 1, 아니면 0 + +adj[1][2]: 1 +adj[2][1]: 1 +adj[2][5]: 1 +adj[5][2]: 1 +... + +2. visited 배열 만들기 +모든 노드를 false로 초기화 한 후, dfs 실행할 때 방문한 노드는 true 할당하기 + +3. dfs 실행 +count = 0으로 정하고, dfs 실행이 끝날 때마다 count++ +for문 내에서 +visited에 방문하지 않은 노드가 있을 경우 그 노드로 dfs 실행 + +for문이 끝나면 return count +*/ + +// const input = require("fs") +// .readFileSync("/dev/stdin") +// .toString() +// .trim() +// .split("\n"); + +const input = ["6 5", "1 2", "2 5", "5 1", "3 4", "4 6"]; +// const input = ["6 8", "1 2", "2 5", "5 1", "3 4", "4 6", "5 4", "2 4", "2 3"]; + +const [[N, M], edges] = [ + input[0].split(" ").map(Number), + input.slice(1).map((el) => el.split(" ").map(Number)), +]; + +const solution = (n, edges) => { + const visited = new Array(n + 1).fill(false); // node 개수만큼 + visited[0] = true; + + const adjacent = new Array(n + 1); + // adjacent 배열을 new Array(n + 1).fill(new Array(n + 1).fill(0))로 했을 경우 왜 밑에 forEach문이 제대로 동작하지 않는가? + // 한번에 여러 인덱스가 같이 바뀌어버리는 이유? + + for (let i = 0; i < adjacent.length; i++) { + adjacent[i] = new Array(n + 1).fill(0); + } + + edges.forEach((edge) => { + adjacent[edge[0]][edge[1]] = 1; + adjacent[edge[1]][edge[0]] = 1; + }); + + const dfs = (node) => { + visited[node] = true; + for (let i = 1; i < adjacent[node].length; i++) { + if (adjacent[node][i] === 1 && !visited[i]) dfs(i); + } + return; + }; + + let count = 0; + for (let i = 1; i <= n; i++) { + if (!visited[i]) { + dfs(i); + count++; + } + } + + return count; +}; + +console.log(solution(N, edges)); diff --git a/jueun/week17/2468.js b/jueun/week17/2468.js new file mode 100644 index 0000000..5b3ef93 --- /dev/null +++ b/jueun/week17/2468.js @@ -0,0 +1,52 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/2468.txt" + ) + .toString() + .split("\n") + .map((el) => el.split(" ").map(Number)); + +const N = input[0][0]; +const map = input.slice(1); + +const solution = (n, map) => { + let maxCount = 0; + + let visited = new Array(n); + for (let i = 0; i < n; i++) visited[i] = new Array(n).fill(false); + + const dfs = (i, j, height) => { + visited[i][j] = true; + if (map[i - 1]?.[j] >= height && !visited[i - 1]?.[j]) + dfs(i - 1, j, height); + if (map[i + 1]?.[j] >= height && !visited[i + 1]?.[j]) + dfs(i + 1, j, height); + if (map[i]?.[j - 1] >= height && !visited[i]?.[j - 1]) + dfs(i, j - 1, height); + if (map[i]?.[j + 1] >= height && !visited[i]?.[j + 1]) + dfs(i, j + 1, height); + }; + + let count; + for (let rainfall = 1; rainfall <= 100; rainfall++) { + count = 0; + visited = new Array(n); + for (let i = 0; i < n; i++) visited[i] = new Array(n).fill(false); + + for (let i = 0; i < n; i++) { + for (let j = 0; j < n; j++) { + if (map[i][j] >= rainfall && !visited[i][j]) { + dfs(i, j, rainfall); + count++; + } + } + } + maxCount = Math.max(maxCount, count); + if (count === 0) break; + } + + return maxCount; +}; + +console.log(solution(N, map)); diff --git a/jueun/week18/1012.js b/jueun/week18/1012.js new file mode 100644 index 0000000..c5eb08b --- /dev/null +++ b/jueun/week18/1012.js @@ -0,0 +1,93 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1012.txt" + ) + .toString() + .split("\n"); + +const T = +input[0]; + +/* +1. 배추밭 만들기 + makeField 함수 구현 + +2. visited 2차원 배열 만들기 + 모든 위치를 false로 초기화 한 후, dfs 실행할 때 방문한 노드는 true 할당하기 + +3. bfs 실행 +worms = 0으로 정하고, bfs 실행이 끝날 때마다 worms++ +for문 내에서 +visited에 방문하지 않은 노드가 있을 경우 그 노드로 bfs 실행 + +for문이 끝나면 return worms +*/ + +const makeField = (m, n, positions) => { + const field = new Array(m); + for (let i = 0; i < m; i++) field[i] = new Array(n).fill(0); + + positions.forEach((xy) => { + field[xy[0]][xy[1]] = 1; + }); + + return field; +}; + +const solution = (m, n, k, posOfCabbages) => { + let worms = 0; + + const cabbageField = makeField(m, n, posOfCabbages); + + const visited = new Array(m); + for (let i = 0; i < m; i++) visited[i] = new Array(n).fill(false); + + const bfs = (i, j) => { + const queue = [[i, j]]; + let nowIdx = 0, + nowI, + nowJ; + while (nowIdx < queue.length) { + [nowI, nowJ] = queue[nowIdx++]; + if (cabbageField[nowI - 1]?.[nowJ] && !visited[nowI - 1]?.[nowJ]) { + visited[nowI - 1][nowJ] = true; + queue.push([nowI - 1, nowJ]); + } + if (cabbageField[nowI + 1]?.[nowJ] && !visited[nowI + 1]?.[nowJ]) { + visited[nowI + 1][nowJ] = true; + queue.push([nowI + 1, nowJ]); + } + if (cabbageField[nowI]?.[nowJ - 1] && !visited[nowI]?.[nowJ - 1]) { + visited[nowI][nowJ - 1] = true; + queue.push([nowI, nowJ - 1]); + } + if (cabbageField[nowI]?.[nowJ + 1] && !visited[nowI]?.[nowJ + 1]) { + visited[nowI][nowJ + 1] = true; + queue.push([nowI, nowJ + 1]); + } + } + return; + }; + + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (cabbageField[i][j] === 1 && !visited[i][j]) { + bfs(i, j); + worms++; + } + } + } + + return worms; +}; + +let MNKIdx = 1; +for (let i = 0; i < T; i++) { + let [M, N, K] = input[MNKIdx].split(" ").map(Number); + let posOfCabbages = input + .slice(MNKIdx + 1, MNKIdx + K + 1) + .map((xy) => xy.split(" ").map(Number)); + MNKIdx += K + 1; + + console.log(solution(M, N, K, posOfCabbages)); +} diff --git a/jueun/week18/1260.js b/jueun/week18/1260.js new file mode 100644 index 0000000..8588a2e --- /dev/null +++ b/jueun/week18/1260.js @@ -0,0 +1,75 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1260.txt" + ) + .toString() + .trim() + .split("\n"); + +const [N, M, V] = input[0].split(" ").map(Number); +const edges = input.slice(1).map((edge) => edge.split(" ").map(Number)); + +const makeAdjMatix = (n, edges) => { + const matrix = new Array(n + 1); + for (let i = 0; i <= n; i++) matrix[i] = new Array(n + 1).fill(0); + edges.forEach((edge) => { + matrix[edge[0]][edge[1]] = 1; + matrix[edge[1]][edge[0]] = 1; + }); + return matrix; +}; + +const dfsSolution = (n, m, v, adjMatrix) => { + const answer = []; + const visited = new Array(n + 1).fill(false); + + const dfs = (node) => { + if (!visited[node]) answer.push(node); + visited[node] = true; + adjMatrix[node].forEach((isConnected, idx) => { + if (isConnected && !visited[idx]) dfs(idx); + }); + }; + + dfs(v); + + return answer.join(" "); +}; + +const bfsSolution = (n, m, v, adjMatrix) => { + /* + 1. 인접 행렬 만들기 + 2. visited 배열 생성 + 3. queue 생성 (처음에 V 넣고 시작) + 4. queue에 있는 노드를 빼고 해당 노드의 (방문하지 않은) 인접 노드들을 queue에 넣는다. 이때 queue에서 빠지면 + visited 배열에 체크하고, 정답에 추가한다. + */ + + const visited = new Array(n + 1).fill(false); + const queue = [v]; + visited[v] = true; + + const answer = []; + let now, + nowIdx = 0; + + while (nowIdx < queue.length) { + now = queue[nowIdx++]; + answer.push(now); + + adjMatrix[now].forEach((isConnected, idx) => { + if (isConnected && !visited[idx]) { + queue.push(idx); + visited[idx] = true; + } + }); + } + + return answer.join(" "); +}; + +const adjMatrix = makeAdjMatix(N, edges); + +console.log(dfsSolution(N, M, V, adjMatrix)); +console.log(bfsSolution(N, M, V, adjMatrix)); diff --git a/jueun/week18/2178.js b/jueun/week18/2178.js new file mode 100644 index 0000000..5d5583e --- /dev/null +++ b/jueun/week18/2178.js @@ -0,0 +1,65 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/2178.txt" + ) + .toString() + .trim() + .split("\n"); + +const [N, M] = input[0].split(" ").map(Number); +const maze = input.slice(1).map((el) => el.split("").map(Number)); + +const solution = (n, m, maze) => { + const visited = new Array(n); + for (let i = 0; i < n; i++) visited[i] = new Array(m).fill(false); + + const bfs = (i, j) => { + const queue = [[i, j]]; + const lengths = [1]; + let nowIdx = 0, + nowI, + nowJ, + nowLength; + visited[0][0] = true; + + let answer; + + while (nowIdx < queue.length) { + nowLength = lengths[nowIdx]; + [nowI, nowJ] = queue[nowIdx++]; + + if (nowI === n - 1 && nowJ === m - 1) { + answer = nowLength; + break; + } + + if (maze[nowI - 1]?.[nowJ] && !visited[nowI - 1]?.[nowJ]) { + visited[nowI - 1][nowJ] = true; + queue.push([nowI - 1, nowJ]); + lengths.push(nowLength + 1); + } + if (maze[nowI + 1]?.[nowJ] && !visited[nowI + 1]?.[nowJ]) { + visited[nowI + 1][nowJ] = true; + queue.push([nowI + 1, nowJ]); + lengths.push(nowLength + 1); + } + if (maze[nowI]?.[nowJ - 1] && !visited[nowI]?.[nowJ - 1]) { + visited[nowI][nowJ - 1] = true; + queue.push([nowI, nowJ - 1]); + lengths.push(nowLength + 1); + } + if (maze[nowI]?.[nowJ + 1] && !visited[nowI]?.[nowJ + 1]) { + visited[nowI][nowJ + 1] = true; + queue.push([nowI, nowJ + 1]); + lengths.push(nowLength + 1); + } + } + + return answer; + }; + + return bfs(0, 0); +}; + +console.log(solution(N, M, maze)); diff --git a/jueun/week18/2644.js b/jueun/week18/2644.js new file mode 100644 index 0000000..ade7fab --- /dev/null +++ b/jueun/week18/2644.js @@ -0,0 +1,60 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/2644.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; +const [p1, p2] = input[1].split(" ").map(Number); +const relations = input.slice(3).map((el) => el.split(" ").map(Number)); + +const makeAdjMatix = (n, edges) => { + const matrix = new Array(n + 1); + for (let i = 0; i <= n; i++) matrix[i] = new Array(n + 1).fill(0); + edges.forEach((edge) => { + matrix[edge[0]][edge[1]] = 1; + matrix[edge[1]][edge[0]] = 1; + }); + return matrix; +}; + +const solution = (n, p1, p2, relations) => { + const bfs = (p1, p2) => { + const adjMatrix = makeAdjMatix(n, relations); + const visited = new Array(n + 1).fill(false); + const queue = [p1]; + const degrees = [0]; + visited[p1] = true; + let now, + nowDegree, + nowIdx = 0; + let answer; + + while (nowIdx < queue.length) { + now = queue[nowIdx]; + nowDegree = degrees[nowIdx++]; + + if (now === p2) { + answer = nowDegree; + break; + } + + adjMatrix[now].forEach((isConnected, idx) => { + if (isConnected && !visited[idx]) { + visited[idx] = true; + queue.push(idx); + degrees.push(nowDegree + 1); + } + }); + } + + return answer; + }; + + return bfs(p1, p2) || -1; +}; + +console.log(solution(n, p1, p2, relations)); diff --git a/jueun/week18/7562.js b/jueun/week18/7562.js new file mode 100644 index 0000000..f548860 --- /dev/null +++ b/jueun/week18/7562.js @@ -0,0 +1,75 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/7562.txt" + ) + .toString() + .trim() + .split("\n"); + +const T = +input[0]; + +const solution = (I, start, end) => { + const visited = new Array(I); + for (let i = 0; i < I; i++) visited[i] = new Array(I).fill(false); + + const bfs = (start, end) => { + let [startI, startJ] = start; + let [endI, endJ] = end; + const queue = [[startI, startJ]]; + const counts = [0]; + let nowIdx = 0, + nowI, + nowJ, + count; + visited[startI][startJ] = true; + const moveRanges = [ + [-2, 1], + [-1, 2], + [1, 2], + [2, 1], + [-2, -1], + [-1, -2], + [2, -1], + [1, -2], + ]; + + let answer; + + while (nowIdx < queue.length) { + count = counts[nowIdx]; + [nowI, nowJ] = queue[nowIdx++]; + + if (nowI === endI && nowJ === endJ) { + answer = count; + break; + } + + moveRanges.forEach(([x, y]) => { + if ( + nowI + x >= 0 && + nowI + x < I && + nowJ + y >= 0 && + nowJ + y < I && + !visited[nowI + x][nowJ + y] + ) { + visited[nowI + x][nowJ + y] = true; + queue.push([nowI + x, nowJ + y]); + counts.push(count + 1); + } + }); + } + + return answer; + }; + + return bfs(start, end); +}; + +let I, start, end; +for (let i = 0; i < T; i++) { + I = +input[1 + i * 3]; + start = input[2 + i * 3].split(" ").map(Number); + end = input[3 + i * 3].split(" ").map(Number); + console.log(solution(I, start, end)); +} diff --git a/jueun/week19/11726.js b/jueun/week19/11726.js new file mode 100644 index 0000000..54c503f --- /dev/null +++ b/jueun/week19/11726.js @@ -0,0 +1,21 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/11726.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; + +const tiles = [BigInt(0), BigInt(1), BigInt(2)]; + +const tiling = (n) => { + if (tiles[n]) return tiles[n]; + tiles.push(tiling(n - 1) + tiling(n - 2)); + + return tiles[n]; +}; + +console.log(String(tiling(n) % BigInt(10007))); diff --git a/jueun/week19/1463.js b/jueun/week19/1463.js new file mode 100644 index 0000000..3cb2654 --- /dev/null +++ b/jueun/week19/1463.js @@ -0,0 +1,34 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1463.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; + +const dp = [0, 0, 1, 1]; + +const solution = (n) => { + for (let i = 4; i <= n; i++) { + if (i % 2 === 0 && i % 3 === 0) { + // 2랑 3으로 둘 다 나누어떨어지는 경우 + dp[i] = Math.min(dp[i / 2], dp[i / 3]) + 1; + } else if (i % 2 === 0) { + // 2로만 나누어떨어지는 경우 + dp[i] = Math.min(dp[i / 2], dp[i - 1]) + 1; + } else if (i % 3 === 0) { + // 3으로만 나누어떨어지는 경우 + dp[i] = Math.min(dp[i / 3], dp[i - 1]) + 1; + } else { + // -1만 가능한 경우 + dp[i] = dp[i - 1] + 1; + } + } + + return dp[n]; +}; + +console.log(solution(n)); diff --git a/jueun/week19/1904.js b/jueun/week19/1904.js new file mode 100644 index 0000000..63b9aa8 --- /dev/null +++ b/jueun/week19/1904.js @@ -0,0 +1,22 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1904.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; + +const tiles = [1, 1]; + +const solution = (n) => { + for (let i = 2; i <= n; i++) { + tiles[i] = (tiles[i - 1] % 15746) + (tiles[i - 2] % 15746); + } + + return tiles[n]; +}; + +console.log(solution(n) % 15746); diff --git a/jueun/week19/2193.js b/jueun/week19/2193.js new file mode 100644 index 0000000..c1df847 --- /dev/null +++ b/jueun/week19/2193.js @@ -0,0 +1,22 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/2193.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; + +const dp = [BigInt(0), BigInt(1)]; + +const pinary = (n) => { + for (let i = 2; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + + return dp[n]; +}; + +console.log(String(pinary(n))); diff --git a/jueun/week19/9655.js b/jueun/week19/9655.js new file mode 100644 index 0000000..3fd3471 --- /dev/null +++ b/jueun/week19/9655.js @@ -0,0 +1,17 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/9655.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; + +const solution = (n) => { + if (n % 2) return "SK"; + else return "CY"; +}; + +console.log(solution(n)); diff --git a/jueun/week20/1182.js b/jueun/week20/1182.js new file mode 100644 index 0000000..d4843fe --- /dev/null +++ b/jueun/week20/1182.js @@ -0,0 +1,33 @@ +// 부분수열의 합 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1182.txt" + ) + .toString() + .trim() + .split("\n"); + +const [n, s] = input[0].split(" ").map(Number); +const nums = input[1].split(" ").map(Number); + +function solution(n, s, nums) { + let count = 0; + function dfs(idx, sum) { + if (idx >= n) return; + + sum += nums[idx]; + + if (sum === s) count += 1; + + dfs(idx + 1, sum - nums[idx]); + dfs(idx + 1, sum); + } + + dfs(0, 0); + + return count; +} + +console.log(solution(n, s, nums)); diff --git a/jueun/week20/17484.js b/jueun/week20/17484.js new file mode 100644 index 0000000..bada5a7 --- /dev/null +++ b/jueun/week20/17484.js @@ -0,0 +1,35 @@ +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/17484.txt" + ) + .toString() + .trim() + .split("\n"); + +const [N, M] = input[0].split(" ").map(Number); +const map = input.slice(1).map((line) => line.split(" ").map(Number)); + +const solution = (map, n, m) => { + let minFuel = 600; + + const explore = (x, y, fuel, direction) => { + if (x === n) { + minFuel = Math.min(minFuel, fuel); + return; + } + fuel += map[x][y]; + for (let i = -1; i <= 1; i++) { + if (x + 1 <= n && y + i >= 0 && y + i < m && direction !== i) + explore(x + 1, y + i, fuel, i); + } + }; + + for (let i = 0; i < m; i++) { + explore(0, i, 0, -2); + } + + return minFuel; +}; + +console.log(solution(map, N, M)); diff --git a/jueun/week20/1912.js b/jueun/week20/1912.js new file mode 100644 index 0000000..2e66b63 --- /dev/null +++ b/jueun/week20/1912.js @@ -0,0 +1,39 @@ +// 연속합 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/1912.txt" + ) + .toString() + .trim() + .split("\n"); + +const n = +input[0]; +const nums = input[1].split(" ").map(Number); + +const solution = (n, nums) => { + let max = Number.MIN_SAFE_INTEGER; + + let lt = 0, + rt = 0; + let sum = 0; + + while (rt < n) { + sum += nums[rt]; + max = Math.max(max, sum); + + if (sum < 0) { + lt = rt + 1; + rt = lt; + if (lt === n) break; + sum = 0; + } else { + rt++; + } + } + + return max; +}; + +console.log(solution(n, nums)); diff --git a/jueun/week20/2503.js b/jueun/week20/2503.js new file mode 100644 index 0000000..e84df67 --- /dev/null +++ b/jueun/week20/2503.js @@ -0,0 +1,65 @@ +// 숫자 야구 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/2503.txt" + ) + .toString() + .trim() + .split("\n"); + +const N = +input[0]; +const logs = input.slice(1).map((line) => line.split(" ").map(Number)); + +const solution = (n, logs) => { + let numCanBeAnswer = 0; + + const countStrikesNBalls = (logNum, num) => { + const logNumArr = logNum.toString().split(""); + const numArr = num.toString().split(""); + let strikes = 0, + balls = 0; + + for (let i = 0; i < 3; i++) { + if (logNumArr[i] === numArr[i]) { + strikes++; + } else if ( + logNumArr[i] === numArr[(i + 1) % 3] || + logNumArr[i] === numArr[(i + 2) % 3] + ) { + balls++; + } + } + + return [strikes, balls]; + }; + + for (let num = 123; num <= 987; num++) { + const numArr = num.toString().split(""); + if ( + numArr.includes("0") || + numArr[0] === numArr[1] || + numArr[1] === numArr[2] || + numArr[0] === numArr[2] + ) + continue; + let check = 0; + let strikes, + balls = 0; + + for (let i = 0; i < n; i++) { + [strikes, balls] = countStrikesNBalls(logs[i][0], num); + if (logs[i][1] === strikes && logs[i][2] === balls) { + check++; + } + } + if (check === n) { + numCanBeAnswer++; + } + } + + return numCanBeAnswer; +}; + +console.log(solution(N, logs)); diff --git a/jueun/week20/3085_2.js b/jueun/week20/3085_2.js new file mode 100644 index 0000000..9e2a6c3 --- /dev/null +++ b/jueun/week20/3085_2.js @@ -0,0 +1,71 @@ +// 사탕 게임 +// reference 참고 + +const fs = require("fs"); +const input = fs + .readFileSync( + process.platform === "linux" ? "/dev/stdin" : __dirname + "/3085.txt" + ) + .toString() + .trim() + .split("\n"); + +const N = +input[0]; +const candy = input.slice(1).map((el) => el.split("")); + +let max = 1; + +for (let i = 0; i < N; i++) { + if (max == N) break; + for (let j = 0; j < N; j++) { + if (max == N) break; + candySwap(i, j); + } +} +console.log(max); + +function candySwap(i, j) { + const dir = [ + [0, 1], + [1, 0], + ]; + dir.forEach((v) => { + const [x, y] = v; + + if ( + i + x > -1 && + j + y > -1 && + i + x < N && + j + y < N && + candy[i + x][j + y] != candy[i][j] + ) { + let temp = candy[i][j]; + candy[i][j] = candy[i + x][j + y]; + candy[i + x][j + y] = temp; + checkRow(); + checkColumn(); + candy[i + x][j + y] = candy[i][j]; + candy[i][j] = temp; + } + }); +} + +function checkRow() { + for (let i = 0; i < N; i++) { + let checkArr = [1]; + for (let j = 1; j < N; j++) { + checkArr[j] = candy[i][j - 1] == candy[i][j] ? checkArr[j - 1] + 1 : 1; + } + max = Math.max(...checkArr, max); + } +} + +function checkColumn() { + for (let i = 0; i < N; i++) { + let checkArr = [1]; + for (let j = 1; j < N; j++) { + checkArr[j] = candy[j - 1][i] == candy[j][i] ? checkArr[j - 1] + 1 : 1; + } + max = Math.max(...checkArr, max); + } +}