- 문제 링크 : boj.kr/16566
- 난이도 : P5
- 태그 : 이분탐색, 유니온파인드
16566번: 카드 게임
첫째 줄에 세 개의 자연수 N, M, K가 주어진다. (1 ≤ M ≤ N ≤ 4,000,000, 1 ≤ K ≤ min(M, 10,000)) 다음 줄에 카드의 번호를 나타내는 M개의 자연수가 주어진다. 각각의 수들은 1 이상이고 N 이하이며 서로
www.acmicpc.net
코드
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define INF 0x7FFFFFFF
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll, ll>;
int p[4000001];
int find(int u){
if(u == p[u]) return u;
return p[u] = find(p[u]);
}
void merge(int u){
int v = u + 1;
u = find(u), v = find(v);
if(u == v) return;
p[u] = v;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m, k;
cin >> n >> m >> k;
vector<int> arr(m);
for(auto &u : arr) cin >> u;
for(int i = 0; i < m; i++) {
p[i] = i;
}
sort(all(arr));
for(int i = 0; i < k; i++) {
int input;
cin >> input;
auto iter = upper_bound(all(arr), input);
int index = find(iter - arr.begin());
cout << arr[index] << "\n";
merge(index);
}
return 0;
}
풀이
내야 할 카드를 이분탐색으로 찾는다는 것은 쉽게 생각할 수 있을 것이다.
이미 낸 카드를 어떻게 처리할 것인지가 문제이다.
유니온 파인드를 응용해서 해결할 수 있다.
연속된 이미 낸 카드를 하나의 집합으로 보고, 그 다음의 내지 않은 카드를 루트로 보아 유니온 파인드를 시행하면 된다.
728x90
'PS' 카테고리의 다른 글
BOJ 2143 : 두 배열의 합 (0) | 2024.03.03 |
---|---|
BOJ 1253 : 좋다 (0) | 2024.03.02 |
BOJ 15900 : 나무 탈출 (1) | 2024.02.29 |
BOJ 1021 : 회전하는 큐 (0) | 2024.02.28 |
BOJ 2178 : 미로탐색 (1) | 2024.02.27 |