-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: 2024-autumn-exercise/sort & parametric search.md
- Loading branch information
Showing
1 changed file
with
231 additions
and
0 deletions.
There are no files selected for viewing
231 changes: 231 additions & 0 deletions
231
slides/2024-autumn-exercise/sort & parametric search.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
--- | ||
marp: true | ||
--- | ||
|
||
# Sort & Parametric Search | ||
소프트웨어학부 진민성 | ||
|
||
--- | ||
|
||
# 좌표 정렬하기 | ||
- 2차원 평면 위의 점 N개를 좌표를 x좌표가 증가하는 순으로, x좌표가 같으면 y좌표가 증가하는 순서로 정렬 | ||
- 많은 방법이 있지만 대부분 2가지 방식으로 구현 | ||
- 직접 구조체를 선언하고 compare함수를 넣어주는 방법 | ||
- 아래처럼 단순하게 pair로 정렬하는 방법 | ||
```cpp | ||
vector<pair<int,int>> v(N); | ||
for(auto &[x,y]:v) cin >> x >> y; | ||
sort(v.begin(), v.end()); | ||
for(auto [x,y]:v) cout << x << ' ' << y << '\n'; | ||
``` | ||
--- | ||
# 수 찾기 | ||
- N개의 정수가 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 문제 | ||
- 2가지 방식 | ||
- 정렬하고 binary search | ||
```cpp | ||
cin >> N; | ||
vector<int> v(N); | ||
for(int &i:v) cin >> i; | ||
sort(v.begin(),v.end()); | ||
cin >> M; | ||
for(int i=0, a;i<M;i++) cin >> a, cout << binary_search(v.begin(),v.end(),a) << '\n'; | ||
``` | ||
|
||
- set을 사용 | ||
```cpp | ||
cin >> N; | ||
set<int> s; | ||
for(int i=0, a;i<N;i++) cin >> a, s.insert(a); | ||
cin >> M; | ||
for(int i=0, a;i<M;i++) cin >> a, cout << s.count(a) << '\n'; | ||
``` | ||
|
||
--- | ||
|
||
# 랜선 자르기 | ||
- $K$개의 랜선을 잘라 $N$개의 같은 길이의 랜선으로 만드는 문제 | ||
- $K$개의 랜선을 잘라 $M$길이의 간선 $N$개를 만들 수 있는가? - 결정문제 | ||
- 단조성을 가지고 있다 -> parametric search | ||
- $l$=1, $r$=랜선 중 최대 길이로 두고 탐색 | ||
|
||
--- | ||
|
||
# 서버실 | ||
- 서버실의 컴퓨터 중 절반 이상이 켜지려면 필요한 시간을 구하는 문제 | ||
- 냉방기가 1분마다 아래에서부터 차오르는 차가운 공기가 컴퓨터 높이만큼 채워질 때 컴퓨터가 켜짐 | ||
|
||
- 차가운 공기의 높이가 $M$일때 켜지는 컴퓨터가 절반 이상인가? - 결정문제 | ||
- 단조성 -> parametric search | ||
- $l$=1, $r$=가장 높은 컴퓨터의 높이로 두고 탐색 | ||
|
||
--- | ||
|
||
# 악덕 사장 | ||
- 마감기한이 있는 일 $N$개를 하면서 직원들이 동일하게 일할 수 있는 최대 시간 k를 찾는 문제. | ||
|
||
- 일을 M시간 동안 할때 모든 일을 마감기한 내에 할수 있는가? - 결정문제 | ||
- 그리디하게 마감기한 순서로 정렬하고 차례대로 처리 | ||
- 단조성 -> parametric search | ||
- $l$=1, $r$=최대 마감기한으로 두고 탐색 | ||
|
||
--- | ||
|
||
# 선물 | ||
- $N$개의 작은 박스의 크기 $A × A × A$를 정육면체 박스를 크기 $L × W × H$의 직육면체 상자에 넣을 때 A의 최댓값을 구하는 문제 | ||
|
||
- 한쪽 변의 길이가 $M$인 정육면체 박스를 사용했을때 직육면체 박스에 N개 이상이 들어가는가? - 결정문제 | ||
- $\lfloor{L\over M}\rfloor \times \lfloor{W\over M}\rfloor \times \lfloor{H\over M}\rfloor \geq N$ | ||
- $l$=1, $r$=min($L$,$W$,$H$)로 하고 탐색 | ||
|
||
--- | ||
|
||
# 곰곰이와 시소 | ||
- N개의 치킨이 놓인 시소에서 균형을 맞추기 위해 받침점의 위치를 구하는 문제 | ||
- 각 치킨의 무게와 위치가 주어졌을 때, 시소가 평행하게 되는 받침점의 위치를 계산해야 함 | ||
|
||
- 받침점이 시소의 왼쪽으로 부터 M만큼 떨어져 있을때 무게중심이 왼쪽이 더큰가? - 결정문제 | ||
- 단조성이 있으므로 parametric search | ||
- 정수가 아닌 실수로 계산을 해야함 | ||
- 실수의 경우에는 종료조건을 $l<r$ 로 줄 수 없기 때문에 반복문으로 적당히 100~500번정도 돌리면 됩니다. | ||
|
||
--- | ||
|
||
# 두 용액 | ||
- 주어진 용액 중 두 개의 용액을 선택해, 그 합이 0에 가장 가까운 값을 만드는 두 용액을 찾는 문제 | ||
|
||
- 정렬하고 앞뒤에서 부터 보면서 합이 0인 값을 찾아가면 됩니다. | ||
- $l=0, r=N-1$로 시작 | ||
- $A[l]+A[r]$이 0보다 작으면 l++, 아니면 r-- | ||
|
||
--- | ||
|
||
# 개똥벌레 | ||
- 개똥벌레가 날아갈 때 파괴해야 하는 장애물의 최소 개수와 그러한 구간의 개수를 구하는 문제 | ||
- 동굴의 길이(N)과 높이(H)가 주어지며, 석순과 종유석의 높이가 번갈아가며 주어짐 | ||
|
||
- 종유석과 석순을 따로 벡터에 저장하고 정렬 | ||
- 개똥벌레가 i번째 구간으로 날아갈때 파괴해야하는 종유석의 개수는 binary search로 셀수 있음 | ||
- 구간을 1부터 N까지 모두 돌아보면서 가장 적게 파괴해야하는 장애물의 개수와 구간의 개수를 세면 됨 | ||
- 시간복잡도는 binary search가 log시간이 걸리므로 $O(Nlog N)$ | ||
|
||
--- | ||
|
||
# 누가 이길까 | ||
- HI팀(N명)과 ARC팀(M명) 간의 모든 대결 결과를 예측하는 문제 | ||
- 각 참가자는 코딩 실력을 가지고 있으며, 더 높은 실력을 가진 참가자가 승리 | ||
|
||
- 각 팀마다 실력순서로 정렬 | ||
- upper_bound와 lower_bound를 사용해서 상대팀에서 나보다 실력이 작은 사람, 같은 사람, 높은 사람의 개수를 log에 셀수 있음 | ||
- 모든 사람을 순회하면서 계산하면 됨 | ||
|
||
--- | ||
|
||
# 공유기 설치 | ||
- N개의 집에 C개의 공유기를 설치하여, 가장 인접한 두 공유기 사이의 거리를 최대화하는 문제 | ||
- 각 집의 좌표는 주어지며, 한 집에는 공유기를 하나만 설치할 수 있음 | ||
|
||
- 각 공유기사이의 거리를 최소 M이상으로 배치하여 C개의 공유기를 모두 설치할 수 있는가? - 결정문제 | ||
- 단조성을 가짐 -> parametric search | ||
|
||
--- | ||
|
||
# 중량제한 | ||
- N개의 섬과 그 사이의 다리가 있는 상황에서, 두 공장 간 물품을 옮길 때 다리의 중량제한을 고려하여 최대로 옮길 수 있는 물품의 중량을 구하는 문제 | ||
- 각 다리는 중량제한이 있으며, 이를 초과하면 다리가 무너지기 때문에 이 제한을 만족하는 최대 중량을 계산해야 함 | ||
|
||
- 2가지 방법으로 해결 할 수 있습니다. | ||
- parametric search & bfs | ||
- 중량제한이 $M$이상인 다리만을 사용하여 A에서 B로 갈수 있는가? - 결정문제 | ||
- A에서 시작해서 중량제한이 $M$이상인 간선만을 사용해서 B를 방문할 수 있는지 확인 | ||
|
||
--- | ||
|
||
- Greedy & Union Find | ||
- Kruskal과 비슷하게 해결할 수 있음 | ||
- 간선의 중량제한을 내림차순으로 정렬하고 하나씩 Union-Find를 이용해서 연결해주고 두 공장이 연결되면 마지막으로 연결한 중량제한을 출력하면 됨 | ||
|
||
--- | ||
|
||
# 꼬인 전깃줄 | ||
- 두 줄로 늘어선 전봇대 사이에 연결된 전선들이 꼬여 있는 상황에서, 꼬임을 없애기 위해 최소한의 전선을 잘라야 하는 문제 | ||
- 전선의 연결 상태를 고려하여 잘라야 할 최소 개수를 구하는 프로그램을 작성하는 것 | ||
|
||
- 기본적인 nlog n LIS문제 | ||
|
||
--- | ||
|
||
# binary search | ||
- 수열을 처음부터 마지막 까지 돌면서 | ||
- 해당 배열에 이분탐색을 돌리고 나온 그 위치에 | ||
- 현재 보고 있는 수 삽입 (마지막이면 배열 하나 키우기) | ||
- 이분탐색에서 나온 인덱스가 그 수를 마지막으로 하는 수열의 lis | ||
- 마지막 배열의 크기가 수열 전체의 lis | ||
|
||
--- | ||
|
||
# Segment tree + DP | ||
- DP[i]를 i까지의 lis 길이라고 하자. | ||
- segment tree는 DP[i]를 관리 | ||
- A[i]에 DP[i]를 업데이트하고 max Seg로 최대값을 관리 | ||
- Seg에서 1,A[i]-1 구간에 쿼리를 날리면 이전까지의 수중에서 가장 큰 DP[i]의 값을 log에 찾을 수 있음 | ||
- seg.qry(q,A[i]-1) + 1로 DP[i]값을 업데이트 | ||
|
||
DP[N]의 값이 lis의 길이 | ||
|
||
--- | ||
|
||
# 통나무 자르기 | ||
- 길이 \( L \)인 통나무를 \( K \)개의 주어진 위치에서 최대 \( C \)번 자르면서, 가장 긴 조각의 길이를 최소화하는 문제 | ||
|
||
- 가장 긴 조각의 길이를 M이하로 자를 수 있는가? - 결정문제 | ||
- parametric search | ||
|
||
--- | ||
|
||
# K번째 수 | ||
- 크기가 N×N인 배열 A는 A[i][j] = i×j로 정의 | ||
- A를 1차원으로 정렬했을때 K번째 수를 구하는 문제 | ||
|
||
- M보다 작은 수의 개수가 N*N/2보다 큰가? - 결정문제 | ||
- parametric search | ||
|
||
--- | ||
|
||
# 시험 | ||
- N개의 시험 성적에서 K개의 시험을 선택해 평균 성적을 최대화하는 문제 | ||
- 각 시험의 성적은 맞힌 문제 수 $P_i$와 총 문제 수 $Q_i$로 주어짐 | ||
- 평균 성적은 $\frac{\sum P_x}{\sum Q_x}$로 정의 | ||
|
||
- 평균 성적이 D이상이 되도록 하는 시험의 조합이 존재하는가? - 결정문제 | ||
- parametric search | ||
- $\frac{\sum P_x}{\sum Q_x} \geq D ~ (i \in X)$ | ||
- $\sum (-Q_iD + P_i) \geq 0 ~ (i \in X)$ | ||
|
||
- $y = −Q_ix + P_i$ 라는 직선의 $x$ 좌표에 $D$를 대입한 값이 가장 큰 상위 $K$개의 직선을 고르는 것이 최적 | ||
- D는 실수 이므로 위의 곰곰이와 시소처럼 원하는 실수 정밀도를 얻을 수 있을 만큼 반복문으로 돌아주면 됩니다. | ||
|
||
--- | ||
|
||
# 날카로운 눈 | ||
- 주어진 정수들 중에서 오직 하나의 정수만 홀수 개로 존재, 나머지는 모두 짝수 개로 존재 | ||
- N개의 입력이 주어지고, 각 입력은 $A, C, B$로 이루어져 있다. | ||
- 이 입력은 $A, A+B, A+2B, \ldots, A+kB$ (단, $ A+kB \leq C)$의 정수들이 정수더미에 포함된다는 의미 | ||
|
||
- 정수 더미에서 홀수 개 존재하는 정수를 찾는 문제 | ||
|
||
- N보다 큰 수의 개수가 홀수개라는 것은 홀수개 존재하는 정수가 N보다 크다는 것을 의미 -> 단조성을 가짐 | ||
- parametric search로 해결이 가능 | ||
- N보다 큰 수의 개수가 홀수개 인가? | ||
|
||
--- | ||
|
||
# 삶의 질 | ||
- $H\times W$영역에서 중간값의 수의 크기가 가장 작은 값을 찾는 문제 | ||
- 어떤 수 M이하의 값이 중간값이 될 수 있는 영역이 존재하는가? - 결정문제 | ||
- 단조성 -> parametric search | ||
- M보다 큰 값은 1, 같은 수는 0, 작은 수는 -1로 바꾸고 | ||
- 누적합을 이용하여 $H\times W$영역에서 중간값이 존재하는 지 판별가능 |