반응형
2075번: N번째 큰 수
첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.
www.acmicpc.net
문제
N×N의 표에 수 N2개 채워져 있다. 채워진 수에는 한 가지 특징이 있는데, 모든 수는 자신의 한 칸 위에 있는 수보다 크다는 것이다. N=5일 때의 예를 보자.
12 | 7 | 9 | 15 | 5 |
13 | 8 | 11 | 19 | 6 |
21 | 10 | 26 | 31 | 16 |
48 | 14 | 28 | 35 | 25 |
52 | 20 | 32 | 41 | 49 |
이러한 표가 주어졌을 때, N번째 큰 수를 찾는 프로그램을 작성하시오. 표에 채워진 수는 모두 다르다.
입력
첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.
출력
첫째 줄에 N번째 큰 수를 출력한다.
예제 입력
5 12 7 9 15 5 13 8 11 19 6 21 10 26 31 16 48 14 28 35 25 52 20 32 41 49
예제 출력
35
풀이
주제를 알지 못했을 때의 플로우
- 말 그대로 N번째 큰 수를 찾는 것, 각 열이 정렬되어 있다는 조건
- 각 열에서 끝 행의 숫자들을 비교해가며 찾는 방식은 어떨까?
- 이렇게도 저렇게도 각 열마다의 숫자가 뒤죽박죽이기때문에 전체의 숫자를 탐색해야 한다
- 최대 1,500의 N 값이고, 최댓값을 하나씩 뺄 경우에, 다음 최댓값을 알아내는 구조가 필요함
- 숫자들을 push하고, 최댓값을 pop 할 수 있는 우선순위 큐(Heap)가 적합함을 알 수 있음
주제를 알고서의 플로우
- N번 째 큰 수를 찾으므로, 전체 수를 최대힙(MaxHeap)에 insert 하고, N번을 pop?
—> 메모리 초과
—> 힙의 insert는 힙의 배열 수에 연관된다 (O(N))
—> 따라서, 힙의 최대 개수를 줄여주는 건 동작에 큰 영향을 미치게 된다 - N개의 힙의 개수 제한을 둔다고 가정하자
N번째 큰 수(a)가 힙에 남아있으려면, N개가 넘어갈 때, a보다 작은 수를 빼면 된다
—> 최소힙을 구현하여, size가 N+1 이 넘어갈 때 pop을 해준다
—> 전체 수를 insert 하고 나면, a가 최소인 N개의 힙이 남아있게 된다
코드 (리뷰 환영)
class MinHeap { constructor() { this.list = [null]; } swap(a, b) { [this.list[a], this.list[b]] = [this.list[b], this.list[a]]; } getParent(current) { return this.list[Math.floor(current / 2)]; } getLeftChildIdx(current) { return current * 2; } getRightChildIdx(current) { return current * 2 + 1; } bubbleUp() { let pos = this.size() - 1; while (pos >= 1) { const parent = this.getParent(pos); const parentIdx = Math.floor(pos / 2); if (!parent) return; if (parent > this.list[pos]) { this.swap(parentIdx, pos); pos = parentIdx; } else return; } } bubbleDown() { let pos = 1; while (pos < this.size()) { const leftIdx = this.getLeftChildIdx(pos), rightIdx = this.getRightChildIdx(pos); let maxIndex = pos; if (leftIdx < this.size() && this.list[leftIdx] < this.list[maxIndex]) maxIndex = leftIdx; if (rightIdx < this.size() && this.list[rightIdx] < this.list[maxIndex]) maxIndex = rightIdx; if (maxIndex !== pos) { this.swap(maxIndex, pos); pos = maxIndex; } else return; } } insert(element) { this.list.push(element); this.bubbleUp(); } pop() { if (this.size() === 2) return this.list.pop(); const answer = this.list[1]; this.list[1] = this.list.pop(); this.bubbleDown(); return answer; } size() { return this.list.length; } empty() { return this.size() === 1; } }
const fs = require("fs"); const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt"; const [_N, ...inputs] = fs.readFileSync(filePath).toString().trim().split("\\n"); const N = +_N; // ----------------------------------- const myQ = new MinHeap(); let answer = -1; const [...nums] = inputs.map((line) => { return line.split(" ").map(Number); }); nums.forEach((line) => { for (let num of line) { myQ.insert(num); if (myQ.size() > N) answer = myQ.pop(); } }); // ----------------------------------- console.log(answer);
여기서 잠깐!
- 사실 해당 코드는 답이 아니다 😲
- 해당 문제는 node JS 에서 풀면 메모리 초과가 거의 나게 되는 문제로,,
정답인 코드들을 보아도 같은 로직이지만,
readline 모듈을 사용하는 등으로 통과된 것으로 추정된다 - (readline 모듈로 해보려는데 잘 몰라서 못함,, 아시면 알려주세요)
- JS 코테는 어느 정도까지 나오는 건지🤔🤔
반응형
'Algorithm' 카테고리의 다른 글
[백준 9184번][Javascript][NodeJs] 동적 계획법 (DP; Dynamic Programming) (0) | 2022.04.09 |
---|---|
[C] 위상정렬(Topology Sort) 개념 및 정리 (1) | 2021.11.18 |
[백준 2178번][C] 미로 탐색 (BFS) (2) | 2021.02.23 |
[백준 2667번][C] 단지번호붙이기 (DFS) (0) | 2021.02.20 |
[C] 너비 우선 탐색(BFS; Breadth First Search) 개념 및 정리 (2) | 2021.02.06 |