Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions Programmers/Level2/159993_미로_탈출.js
Original file line number Diff line number Diff line change
@@ -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;
}
57 changes: 57 additions & 0 deletions Programmers/Level3/77486_다단계_칫솔_판매.js
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 2 additions & 0 deletions Programmers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand All @@ -67,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) |