문제
https://www.acmicpc.net/problem/2075
2075번: N번째 큰 수
첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.
www.acmicpc.net
솔루션
N^2의 격자판에서 N번째로 큰 수를 뽑아야 한다.
처음에 모든 수를 다 담은 뒤, 5번 째 큰 수를 뽑으려 했는데, 메모리 제한이 12MB인 것을 모르고 제출을 했다가.. 메모리 초과를 받았다.
따라서 우선순위 큐를 이용해 이를 해결하였는데, 원리는 다음과 같다.
입력으로 들어온 수 중에서 가장 큰 수 N개만 남겨놓고 모든 값들은 우선순위 큐에서 제거한다.
그러면 N번째 큰 수가 자동으로 pq.top()에 위치하게 되므로, 출력을 하면 된다.
코드
#include <iostream>
#include <queue>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int N;
cin >> N;
priority_queue<int,vector<int>, greater<int>> pq;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int value;
cin >> value;
pq.push(value);
if (pq.size() > N) pq.pop();
}
}
cout << pq.top();
}
문제
https://www.acmicpc.net/problem/1715
1715번: 카드 정렬하기
정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장
www.acmicpc.net
솔루션
카드를 합치는 데, 가장 작은 것 부터 합쳐가는 것이 비교 회수가 최소가 된다.
따라서 우선순위 큐를 이용하여 가장 작은 두 수를 뽑고, 더한 뒤 다시 우선 순위 큐에 넣어준다.
이때 큐에 넣는 값을 계속 정답에 더하면 된다.
코드
#include <iostream>
#include <queue>
using namespace std;
int N;
priority_queue<int> pq;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N;
for (int i = 0; i < N; i++) {
int value;
cin >> value;
pq.push(-value);
}
long long ans = 0;
while (pq.size() > 1) {
int f = -pq.top();
pq.pop();
int s = -pq.top();
pq.pop();
ans += (f + s);
pq.push(-(f + s));
}
cout << ans << '\n';
}
'스터디' 카테고리의 다른 글
알고리즘 스터디 - 큐 (0) | 2023.07.20 |
---|---|
Deque 활용 문제 풀이 (0) | 2023.06.01 |
[스터디] 연결리스트(Linked List) (2) | 2023.05.18 |
1-1 중복이 없는가? (0) | 2023.05.11 |