From 41582b7237a2d3e503c33ea513eb8556c80fd01e Mon Sep 17 00:00:00 2001 From: yoouyeon Date: Tue, 21 Oct 2025 10:49:18 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=92=A1=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=EB=A8=B8=EC=8A=A4=2077486=20-=20=EB=8B=A4=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=20=EC=B9=AB=EC=86=94=20=ED=8C=90=EB=A7=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...3\354\206\224_\355\214\220\353\247\244.js" | 57 +++++++++++++++++++ Programmers/README.md | 1 + 2 files changed, 58 insertions(+) create mode 100644 "Programmers/Level3/77486_\353\213\244\353\213\250\352\263\204_\354\271\253\354\206\224_\355\214\220\353\247\244.js" diff --git "a/Programmers/Level3/77486_\353\213\244\353\213\250\352\263\204_\354\271\253\354\206\224_\355\214\220\353\247\244.js" "b/Programmers/Level3/77486_\353\213\244\353\213\250\352\263\204_\354\271\253\354\206\224_\355\214\220\353\247\244.js" new file mode 100644 index 0000000..a9c8f14 --- /dev/null +++ "b/Programmers/Level3/77486_\353\213\244\353\213\250\352\263\204_\354\271\253\354\206\224_\355\214\220\353\247\244.js" @@ -0,0 +1,57 @@ +/* +⭐️ 문제 정보 ⭐️ +문제 : 77486 - 다단계 칫솔 판매 +레벨 : Level 3 +링크 : https://school.programmers.co.kr/learn/courses/30/lessons/77486 +*/ + +/** NOTE + * - 아래에서 위로 올라가는 방식 => 트리 저장 방법 : 자식 노드의 부모 노드가 무엇인지를 저장한다. + * - 이익 분배 결과 저장 : enroll과 동일한 순서를 갖는 배여 => 이름에 해당하는 인덱스도 함께 저장해야겠다. + * - currentProfit : 현재 노드가 가진 이익 => 이 이익금이 0이 되거나, 부모 노드가 없을 때 까지 반복하는 느낌으로 진행! + */ + +const PRICE = 100; + +function solution(enroll, referral, seller, amount) { + let answer = Array.from({ length: enroll.length }, () => 0); + const index = new Map(); // key: 판매원 이름, value: enroll과 answer 상의 인덱스 + const parent = new Map(); // key: 자식 노드 판매원 이름, value: 부모 노드 판매원 이름 + + // Map 초기화 + for (let idx = 0; idx < enroll.length; idx++) { + index.set(enroll[idx], idx); + if (referral[idx] !== "-") { + // 추천인이 있는 경우에만 저장한다. + parent.set(enroll[idx], referral[idx]); + } + } + + // 이익 분배 재귀함수 + // name: 이 이익을 들고 있는 판매원 (이익을 상위로 분배하거나 다 갖는다.) + // currentProfit: 분배할 이익 + function distribute(name, currentProfit) { + if (name === undefined || currentProfit <= 0) { + // 분배 못함 + return; + } + const distributedProfit = Math.floor(currentProfit * 0.1); + const retainedProfit = currentProfit - distributedProfit; + + // 남은 금액을 현재 판매원에게 준다. + answer[index.get(name)] += retainedProfit; + // 상위 추천인이 없거나 분배할 이익이 없다면 분배를 중단한다. + if (parent.get(name) === undefined || distributedProfit === 0) { + return; + } + // 남은 이익을 상위 판매원이 다시 분배한다. + distribute(parent.get(name), distributedProfit); + } + + // seller와 amount를 분배 + for (let idx = 0; idx < seller.length; idx++) { + distribute(seller[idx], amount[idx] * PRICE); + } + + return answer; +} diff --git a/Programmers/README.md b/Programmers/README.md index 04af503..133a193 100644 --- a/Programmers/README.md +++ b/Programmers/README.md @@ -52,6 +52,7 @@ | 72411 | 메뉴 리뉴얼 | [72411_메뉴_리뉴얼.js](Level2/72411_메뉴_리뉴얼.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/72411) | | 76502 | 괄호 회전하기 | [76502_괄호_회전하기.js](Level2/76502_괄호_회전하기.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/76502) | | 77484 | 로또의 최고 순위와 최저 순위 | [77484_로또의_최고_순위와_최저_순위.js](Level1/77484_로또의_최고_순위와_최저_순위.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/77484) | +| 77486 | 다단계 칫솔 판매 | [77486_다단계_칫솔_판매.js](Level3/77486_다단계_칫솔_판매.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/77486) | | 77885 | 2개 이하로 다른 비트 | [77885_2개_이하로_다른_비트.js](Level2/77885_2개_이하로_다른_비트.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/77885) | | 81303 | 표 편집 | [81303_표_편집.js](Level3/81303_표_편집.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/81303) | | 87390 | n^2 배열 자르기 | [87390_n^2_배열_자르기.js](Level2/87390_n^2_배열_자르기.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/87390) | From 213844162e3cd01d5cdc887adf0ba784f1a412c3 Mon Sep 17 00:00:00 2001 From: yoouyeon Date: Tue, 21 Oct 2025 10:50:04 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=92=A1=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=EB=A8=B8=EC=8A=A4=20159993=20-=20=EB=AF=B8=EB=A1=9C?= =?UTF-8?q?=20=ED=83=88=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\353\241\234_\355\203\210\354\266\234.js" | 112 ++++++++++++++++++ Programmers/README.md | 1 + 2 files changed, 113 insertions(+) create mode 100644 "Programmers/Level2/159993_\353\257\270\353\241\234_\355\203\210\354\266\234.js" diff --git "a/Programmers/Level2/159993_\353\257\270\353\241\234_\355\203\210\354\266\234.js" "b/Programmers/Level2/159993_\353\257\270\353\241\234_\355\203\210\354\266\234.js" new file mode 100644 index 0000000..00cf627 --- /dev/null +++ "b/Programmers/Level2/159993_\353\257\270\353\241\234_\355\203\210\354\266\234.js" @@ -0,0 +1,112 @@ +/* +⭐️ 문제 정보 ⭐️ +문제 : 159993 - 미로 탈출 +레벨 : Level 2 +링크 : https://school.programmers.co.kr/learn/courses/30/lessons/159993 +*/ + +/** NOTE + * - BFS 2번이 관건 + * - 굳이 시작 지점부터의 거리를 계속 갖고 다닐 필요가 없다 => 이러면 BFS 2번 사이에 거리를 저장하고 있어야 해서 구조가 복잡해진다. + * - 첫번째 BFS : 시작 지점에서 레버까지의 최단 거리 계산 + * - 두번째 BFS : 레버에서 출구까지의 최단 거리 계산 + * - 두 거리의 합이 답이 된다. + * - 각 BFS 결과 도달할 수 없는 경우가 있다면 -1 반환 + * - 큐 구현을 Map으로 해봤다. + */ + +class Queue { + queue = new Map(); + head = 0; + tail = 0; + + constructor() {} + + get size() { + return this.tail - this.head; + } + + enqueue(element) { + this.queue.set(this.tail++, element); + } + + dequeue() { + const ret = this.queue.get(this.head); + if (!ret) { + return undefined; + } + this.queue.delete(this.head++); + return ret; + } + + isEmpty() { + return this.head === this.tail; + } +} + +function BFS(maps, start, goal) { + const R = maps.length; + const C = maps[0].length; + const visited = Array.from({ length: R }, () => + Array.from({ length: C }, () => false) + ); // 숫자 값을 저장해서 거리 저장에 활용할수도 있음 + const dir = [ + [0, 1], + [0, -1], + [1, 0], + [-1, 0], + ]; + const queue = new Queue(); + + queue.enqueue([start, 0]); + visited[start.r][start.c] = true; + + while (!queue.isEmpty()) { + const [pos, dist] = queue.dequeue(); + + if (pos.r === goal.r && pos.c === goal.c) { + return dist; + } + + // 상하좌우 이동, 이동 가능한 경우에만 큐에 넣는다. + for (const [dirR, dirC] of dir) { + const newR = pos.r + dirR; + const newC = pos.c + dirC; + + if (newR < 0 || newR >= R || newC < 0 || newC >= C) continue; + if (maps[newR][newC] === "X") continue; + if (visited[newR][newC]) continue; + + visited[newR][newC] = true; + queue.enqueue([{ r: newR, c: newC }, dist + 1]); + } + } + + // goal에 도달할 수 없는 경우 + return -1; +} + +function solution(maps) { + const R = maps.length; + const C = maps[0].length; + + // 지도 탐색 + let S, E, L; + for (let r = 0; r < R; r++) { + for (let c = 0; c < C; c++) { + if (maps[r][c] === "S") S = { r, c }; + else if (maps[r][c] === "E") E = { r, c }; + else if (maps[r][c] === "L") L = { r, c }; + } + } + + // S-L 최단 거리 구하기 + const distToLever = BFS(maps, S, L); + if (distToLever === -1) return -1; + + // L-E 최단 거리 구하기 + const distToExit = BFS(maps, L, E); + if (distToExit === -1) return -1; + + return distToLever + distToExit; +} diff --git a/Programmers/README.md b/Programmers/README.md index 133a193..2e51a38 100644 --- a/Programmers/README.md +++ b/Programmers/README.md @@ -68,6 +68,7 @@ | 121683 | 외톨이 알파벳 | [121683_외톨이_알파벳.js](Unrated/121683_외톨이_알파벳.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/121683) | | 131127 | 할인 행사 | [131127_할인_행사.js](Level2/131127_할인_행사.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/131127) | | 150370 | 개인정보 수집 유효기간 | [150370_개인정보_수집_유효기간.js](Level1/150370_개인정보_수집_유효기간.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/150370) | +| 159993 | 미로 탈출 | [159993_미로_탈출.js](Level2/159993_미로_탈출.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/159993) | | 159994 | 카드 뭉치 | [159994_카드_뭉치.js](Level1/159994_카드_뭉치.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/159994) | | 258711 | 도넛과 막대 그래프 | [258711_도넛과_막대_그래프.js](Level2/258711_도넛과_막대_그래프.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/258711) | | 340212 | [PCCP 기출문제] 2번 퍼즐 게임 챌린지 | [340212_[PCCP_기출문제]_2번_퍼즐_게임_챌린지.js](Level2/340212_[PCCP_기출문제]_2번_퍼즐_게임_챌린지.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/340212) |