일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 좌표압축
- 이분탐색
- dfs
- 삼분탐색
- lca
- 투포인터
- 수학
- 위상정렬
- boj
- DisjointSet
- MST
- 구현
- 이분매칭
- 비트마스크
- 이진탐색
- 펜윅트리
- LazyPropagation
- 다익스트라
- 정렬
- 세그먼트트리
- 브루트포스
- 크루스칼
- lis
- 누적합
- BFS
- 에라토스테네스의 체
- 백준
- 플로이드와샬
- 그리디
- DP
Archives
- Today
- Total
lastknight00
[백준]카드 게임(16566) 본문
문제 링크 : [백준]카드 게임(16566)
문제 설명
1~N 사이의 수 중, M개의 중복없는 숫자가 주어집니다.
K개의 수(Vi)가 주어지는데, 위에서 주어진 수 중, Vi보다 큰 수 중 가장 작은 수를 출력하세요.
단, 한번 사용한 수는 다시 사용 할 수 없습니다.
입력
N(주어질 수들의 범위, 1 <= N <= 4,000,000)
M(주어질 카드의 수, 1 <= M <= 4,000,000)
K(1 <= K <= min(M, 10,000))
Ci(주어진 카드의 값, 1 <= Ci <= N)
Vi(대상이 될 카드의 값, 1 <= Vi <= N)
10 7 5
2 5 3 7 8 4 9
4 1 1 3 8
출력
5
2
3
4
9
카테고리
#이진탐색 #DisjointSet #정렬
시간 복잡도 상한
O(KlogM) 혹은 O(KlogN)
해결 방법
- 주어진 카드를 정렬 한 뒤, 이진 탐색으로 upper_bound를 검색하면 될 것 같습니다.
1-1. 시간 복잡도는 O(MlogM + MlogM)일 것 같습니다.
1-2. 카드 정렬 : MlogM
1-3. upper_bound : MlogM - 그러나 한번 사용한 카드는 다시 사용 할 수 없다는 큰 문제가 있습니다.
- 사용한 카드를 마킹하는 순간부터 upper_bound는 사용 할 수 없습니다.
- 그렇다고 사용한 카드의 수를 조작하여 맨 뒤, 혹은 맨 앞으로 보내버리려고 해도 매번 정렬을 해야하기 때문에 M2 이상의 시간복잡도가 발생합니다.
- 위 문제를 해결하기 위해서, 이미 사용된 카드를 다시 사용하려고 한다면, 자신보다 큰 값 중 사용되지 않은 가장 작은 카드를 빠르게 구해야 합니다.(logM 이하)
- 사용한 카드들의 연속된 구간들이 그 다음 칸, 즉 그 구간들 중 가장 큰 값 바로 오른쪽 카드(큰 수 중 가장 작은 수)를 가리키게 합니다.
- 나중에 두개 이상의 구간이 합쳐질 수도 있으니 그런 문제들까지 고려한다면, 사용된 연속 구간을 그룹으로 관리하는 것이 좋을 것 같습니다.
- 따라서 DisjointSet으로 사용된 카드 구간들을 관리하면 됩니다.
시간복잡도
O(KlogM)
코드
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,k,d[4000000],e[4000001],i;
int f(int a){
return a==e[a]?e[a]:e[a]=f(e[a]);
}
void u(int a,int b){
e[f(a)]=e[f(b)];
}
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m>>k;
for(;i<m;i++)cin>>d[i];
for(i=1;i<=n;i++)e[i]=i;
sort(d,d+m);
while(k--){
cin>>i;
n=f(upper_bound(d,d+m,i)-d);
cout<<d[n]<<"\n";
u(n,n+1);
}
}
'PS' 카테고리의 다른 글
[백준]전구 끄기(14927) (0) | 2020.06.29 |
---|---|
[백준]불 끄기(14939) (0) | 2020.06.29 |
[백준]본대 산책2(12850) (0) | 2020.06.26 |
[백준]Dance Dance Revolution(2342) (0) | 2020.06.26 |
[백준] 거짓말(1043) (0) | 2020.06.25 |
Comments