3. POSTECH Programming Contest
- 어떻게 하면 신입생들이 더 쉽게 풀 수 있을까?
- 어떻게 하면 ICPC Rule에 더 맞게 출제할 수 있을까?
1. 모든 문제를 푼 팀이 없을 것
2. 모든 문제는 한 팀 이상에게 풀릴 것
3. 모든 팀이 한 문제 이상 풀 것
올해의 목표
4. POSTECH Programming Contest
- 강병지: A – Scoring Hack, D – Conquering A Castle, G – Team Selection
- 임병찬: B – Good Pizza, Great Pizza, E – Delicious Pineapple Pizza, H – Pineapple Advertising,
J – Almost-K Increasing Subsequence
- 정현식: C – Heights, F – Linear-Feedback Shift Register, I – Kaka & Bebe
문제 출제
5. POSTECH Programming Contest
- Dynamic Programming을 사용해서 해결할 수 있다.
- DP[x][k][i]를 x점을 k턴 안에, i번의 x2 연산을 사용해서 만들 수 있을 때 true, 그렇지 않을 때 false라고 하자.
- 이 경우 D[x][k][i]는
(x >= a and D[x-a][k-1][i] ) (x-a점에서 a점을 더해 x점을 만드는 경우) or
(x >= b and D[x-b][k-1][i] ) (x-b점에서 b점을 더해 x점을 만드는 경우) or
(x %2 == 0 and i <= k/10 and D[x/2][k-1][i-1] ) (x/2 점에서 점수를 두 배로 해 x점을 만드는 경우)
로 나타난다.
- 따라서 각 D[x][k][i]는 O(1)에 계산 가능하다.
- 각 D[x][k][i] 를 계산한 뒤에 n <= x < n+a를 만족하는 x 중에서 D[x][k][i]를 만족하는 k의 최솟값을 구하면
답이 된다.
A - Scoring Hack
Scoring Hack
6. POSTECH Programming Contest
- 게임이론 문제이다.
- 𝑖=1
𝑛
2−𝑑 𝑖 ≥ 1 인 경우 𝑑𝑖 들의 multiset X를 다음과 같은 두 개의 multiset A, B로 나눌 수 있다.
- 𝑑 𝑖∈𝐴 2−𝑑 𝑖 ≥
1
2
, 𝑑 𝑖∈𝐵 2−𝑑 𝑖 ≥
1
2
, 𝐴 ∩ 𝐵 = ∅, 𝐴 ∪ 𝐵 = 𝑋
- 증명은 multiset X의 크기 n에 대해 수학적 귀납법을 사용하면 보일 수 있다.
D - Conquering A Castle
Conquering A Castle
7. POSTECH Programming Contest
Conquering A Castle
- 반 대 로 𝑖=1
𝑛
2−𝑑 𝑖 < 1 인 경 우 , X 를 A 와 B 두 개 의 multiset 으 로 어 떻 게 나 누 더 라 도 , 𝑑 𝑖∈𝐴 2−𝑑 𝑖 <
1
2
,
𝑑 𝑖∈𝐵 2−𝑑 𝑖 <
1
2
둘 중 하나는 만족한다.
- A의 필승 전략은 𝑖=1
𝑛
2−𝑑 𝑖 ≥ 1 인 경우 존재한다.
- 군사들을 𝑑 𝑖∈𝐴 2−𝑑 𝑖 ≥
1
2
, 𝑑 𝑖∈𝐵 2−𝑑 𝑖 ≥
1
2
, 𝐴 ∩ 𝐵 = ∅, 𝐴 ∪ 𝐵 = 𝑋 를 만족하도록 A와 B, 둘로 나누어서 서로 다른
길에 배치하면 된다. 이 경우 한 턴이 지나고 나면, 다시 𝑖=1
𝑛
2−𝑑 𝑖 ≥ 1 가 만족되므로, 같은 전략을 반복하면
결국 승리하게 된다.
- 반대로 B의 필승전략은 𝑖=1
𝑛
2−𝑑 𝑖 < 1인 경우 존재하며 𝑑 𝑖∈𝐴 2−𝑑 𝑖 <
1
2
, 인 경우 B에 있는 군사를 모두 없애고, 그
렇지 않은 경우 A에 있는 군사를 모두 없애 각 턴에서 𝑖=1
𝑛
2−𝑑 𝑖 < 1 조건을 유지시키는 것이다.
8. POSTECH Programming Contest
- 어떤 역할군 순서로 팀을 선택할지, 5!개의 경우가 존재한다.
- 역할군의 순서가 주어져 있을 때, dynamic programming을 통해,
- DP[i][j]를 1~i번째 후보자들에게, 1~j번째의 역할군을 배정할 때 얻을 수 있는 실력의 합의 최댓값이라고 하자.
- DP[i][j] = max(DP[i-1][j] (i번째 후보자에게 j번째 역할군을 배정하지 않는 경우),
DP[i-1][j-1] + i번째 후보자의 j번째 역할군 실력 (i번째 후보자에게 j번째 역할군을 배정하는 경우))
로 나타난다.
- 따라서 DP[n][5]가 위의 순서로 팀을 선택할 때 얻을 수 있는 실력의 합의 최댓값이고, O(5n)에 구할 수 있다.
- 가능한 모든 순서에 대해 계산해서 최댓값을 구하면 O(5!*5*n) 에 실력의 합의 최댓값을 구할 수 있다.
G - Team Selection
Kaka & Bebe
9. POSTECH Programming Contest
- 마름모는 기울어진 정사각형이기 때문에, 대각선의 길이를 𝐶라고 하면, 넓이는
𝐶2
2
다.
- 대각선의 길이는 어떻게 구할까?
- 모든 점이 𝑦 = 𝑥 + 𝑎1와 𝑦 = 𝑥 + 𝑎2사이에 존재한다면, 𝐶는 𝑎1 − 𝑎2 보다 커야 한다.
- 마찬가지로, 모든 점이 𝑦 = 𝑥 + 𝑏1와 𝑦 = 𝑥 + 𝑏2사이에 존재한다면, 𝐶는 𝑏1 − 𝑏2 보다 커야 한다.
- 𝐶가 작을수록 넓이가 작아지므로, 𝐶 = max( 𝑎1 − 𝑎2 , 𝑏1 − 𝑏2 ).
- 𝑎1, 𝑎2, 𝑏1, 𝑏2는 모두 𝑂(𝑛) 시간 안에 계산해 낼 수 있다.
B – Good Pizza, Great Pizza
Good Pizza, Great Pizza
10. POSTECH Programming Contest
Good Pizza, Great Pizza
- 𝐶의 범위는 0이상 40억 이하다.
- 𝐶2
은 long long int 범위를 초과할 수 있다!
- 𝐶 = 2𝑘라면, 넓이는 2𝑘2
이다.
- 𝐶 = 2𝑘 + 1이라면, 넓이는 2𝑘2
+ 2𝑘 + 0.5다.
11. POSTECH Programming Contest
- 우리는 파인애플과 도우를 한개씩 쌍을 만들어 줘야 한다. 즉, 파인애플과 도우의 매칭이라고 생각할 수 있다.
- 적절한 값 h가 있다고 하자. 파인애플과 도우를 Bipartite Matching을 하는데, 파인애플과 도우를 연결할 조건이
“파인애플의 품질 XOR 도우의 품질 ≥ h” 라고 하자.
- 만약 매칭이 되면? 최소값이 h 이상이 되게 하는 파인애플과 도우의 쌍이 존재한다. 즉, 답은 h 이상이다.
- 만약 매칭이 안되면? 어떻게 해도 최소값이 h 이상이 되게 만들 수 없다. 즉, 답은 h 미만이다.
- 즉, h를 기준으로 Binary Search가 가능하다.
E – Delicious Pineapple Pizza
Delicious Pineapple Pizza
12. POSTECH Programming Contest
Delicious Pineapple Pizza
- h는 0이상 231
이하므로 Iteration 수는 log 231
= 31번이다.
- 각 Iteration마다, Flow Graph를 만들고 Maximum Matching을 구한다.(Bipartite Graph의 Maximum Matching은
Maximum Flow로 구할 수 있다.)
- 𝑉 = 𝑂 𝑛 , 𝐸 = 𝑂 𝑛2
, 𝐹 = 𝑂(𝑛)이고 Ford-Fulkerson은 𝑂(𝐹𝐸)의 시간에 동작하므로, 한 Iteration당 𝑂(𝑛3
)의 시간
이 소요된다.
- 전체 Time Complexity = 𝑂(31𝑛3
). 무난하게 AC된다.
- 추가) Ford-Fulkerson말고 Dinic Algorithm을 사용할 수 있다. Dinic은 𝑂 𝑉2
𝐸 = 𝑂(𝑛4
)이 소요된다. 하지만, 모
든 capacity가 0 혹은 1이면 Dinic은 𝑂(min 𝑉
2
3, 𝐸
1
2 𝐸)가 걸린다는게 알려져 있다.
- 즉, Dinic을 사용할시 Time Complexity = 𝑂(31𝑛
8
3).
13. POSTECH Programming Contest
- 핵심 아이디어: 한번 집 a를 들렸다면, 다음에 다시 집 a를 들릴 때, 다시 탐색할 필요가 없다. 왜냐하면, 새로
피자를 좋아하게 된 집은 무조건 0개기 때문이다.
- 쿼리를 받으며, 한번도 안들린 집이면 탐색하고, 한번이라도 들린 집이면 0을 출력하고 탐색하지 않는다.
- 한번 탐색할때는, 그냥 주위에 있는 집 하나하나 탐색한다.
- Time Complexity = 𝑂(𝑁 + 𝑑𝑖 + 𝑄). 𝑑𝑖 = 2𝑀 이므로, 이 알고리즘은 𝑂(𝑁 + 𝑀 + 𝑄)에 동작한다.
H – Pineapple Advertising
Pineapple Advertising
14. POSTECH Programming Contest
- 문제를 간단히 하기 위해, K는 1이고 𝑏𝑖 > 𝑏𝑖+1라고 가정하자.
- 그러면, 𝑏1 ≤ 𝑏2 ≤ ⋯ ≤ 𝑏𝑖, 𝑏𝑖+1 ≤ 𝑏𝑖+2 ≤ ⋯ ≤ 𝑏 𝑚이다.
- B가 A의 subsequence므로, 적당한 h가 존재해서, 𝑏1~𝑏𝑖는 𝑎1~𝑎ℎ의 subsequence,
- 𝑏𝑖+1~𝑏 𝑚은 𝑎ℎ+1~𝑎 𝑛의 subsequence다.
- 따라서, 모든 h에 대해, 𝑎1~𝑎ℎ의 LIS의 길이 + 𝑎ℎ+1~𝑎 𝑛의 LIS의 길이의 최대값을 구하면 된다.
J - Almost-K Increasing Subsequence
Almost-K Increasing Subsequence
15. POSTECH Programming Contest
Almost-K Increasing Subsequence
- K>1이라면? K+1개의 partition을 만든다!
- 수열 A를 서로 겹치지 않는 K+1개의 segment로 나눈다고 하자.
- 즉, 𝑎1~𝑎 𝑛 = 𝑎1~𝑎ℎ1
/𝑎ℎ1+1~𝑎ℎ2
/.../𝑎ℎ 𝐾+1~𝑎 𝑛
- Longest Almost-K Increasing Subsequence의 길이는 K+1개의 segment의 LIS 합의 최대값과 같다.
- K+1개의 segment의 LIS 합의 최대값은 어떻게 찾을까?
17. POSTECH Programming Contest
- 다양한 풀이가 존재합니다.
- 헤론의 공식을 사용하는 풀이와 헤론의 공식을 사용하지 않는 풀이로 나뉩니다.
헤론의 공식이란?
각 변의 길이를 𝑎, 𝑏, 𝑐 라 하자. 𝑠 =
𝑎+𝑏+𝑐
2
로 정의 할 때 넓이 𝑆는 𝑆 = 𝑠 𝑠 − 𝑎 𝑠 − 𝑏 𝑠 − 𝑐 이다.
C - Heights
Heights
19. POSTECH Programming Contest
Heights
풀이 2)
- 넓이 𝑆에 대해 2𝑆 = 𝑎ℎ 𝑎 = 𝑏ℎ 𝑏 = 𝑐ℎ 𝑐. 즉 𝑎 =
2𝑆
ℎ 𝑎
, 𝑏 =
2𝑆
ℎ 𝑏
, 𝑐 =
2𝑆
ℎ 𝑐
- 임의로 잡은 어떤 값 𝑥에 대해서, 𝑎′
=
2𝑥
ℎ 𝑎
, 𝑏′
=
2𝑥
ℎ 𝑏
, 𝑐′
=
2𝑥
ℎ 𝑐
라고 하자.
- 이를 헤론의 공식에 대입해 얻은 넓이를 𝑦라 하자. 우리가 원하는 값 𝑆는 𝑥 = 𝑦일 때 𝑥이다.
- 만약 𝑥 > 𝑦라면, 𝑦는 𝑥2
에 비례하기 때문에 𝑆 > 𝑥이다. 만약 𝑥 < 𝑦라면, 𝑆 < 𝑥이다.
- 𝑆의 최소값과 최대값은 문제의 조건에 따라서 대략적으로 구할 수 있다. 이를 통해 𝑥에 대한 이분 탐색을 시행해
𝑆를 구한다.
20. POSTECH Programming Contest
Heights
풀이 3) (헤론의 공식 X)
- 가장 긴 변을 𝑐라고 하자.
- 오른쪽 그림과 같이 수선을 그어 𝑘를 정의할 수 있다.
- 𝑐를 추측한 값 𝑥에 대해, 𝑎′
=
ℎ 𝑐
ℎ 𝑎
𝑥, 𝑏′
=
ℎ 𝑐
ℎ 𝑏
𝑥.𝑐′
= 𝑎′2
− ℎ 𝑐
2
+ 𝑏′2
− ℎ 𝑐
2
.
- 𝑐값은 𝑐′
= 𝑥일 때 𝑥이다. 𝑐′
− 𝑥 는 𝑥에 대해 단조증가 하기 때문에, 풀이 2와 마찬가지로 𝑥에 대해 이분 탐색이
가능하다. (단조증가에 대한 엄밀한 증명은 생략, 스스로 생각해보세요!)
이외에도 정말 다양한 풀이들이 있음!
𝑎 𝑏
𝑐
𝑘 𝑐 − 𝑘
ℎ 𝑐
21. POSTECH Programming Contest
풀이 1)
- 모든 경우의 수를 확인하여, 사전 순으로 가장 빠른 것을 고른다.
- 단순하게 풀면 236
이므로 시간 내에 불가능.
F - Linear-Feedback Shift Register
Linear-Feedback Shift Register
22. POSTECH Programming Contest
Linear-Feedback Shift Register
풀이 2)
- Meet in the middle을 사용해 풀 수 있다.
- 𝑟36 이후의 𝑟𝑖는 결국 𝑟0~𝑟35 중 일부를 XOR한 것이며,
이는 𝑟0~𝑟17에 대한 XOR 식과 𝑟18~𝑟35에 대한 XOR 식으로 나타낼 수 있다.
- 이를 수식으로 표현하면, 𝑟𝑖 = 𝑓𝑖(𝑟0, 𝑟1, … , 𝑟17)⨂𝑓𝑖
′
𝑟18, 𝑟19, … , 𝑟35 라고 쓸 수 있다.
- 이 때, XOR은 𝑎⨂𝑎 = 0이고 𝑎 = 𝑏 ⇔ 𝑎⨂𝑐 = 𝑏⨂𝑐가 성립함에 유의한다.
23. POSTECH Programming Contest
Linear-Feedback Shift Register
- 𝑟18~𝑟35에 대해 사전 순으로 순회를 돌면서, 𝑟𝑖⨂𝑓𝑖
′
𝑟18, 𝑟19, … , 𝑟35 값들을 구하고, 이를 map에 저장한다.
(map[ 𝑟𝑖⨂𝑓𝑖
′
𝑟18, 𝑟19, … , 𝑟35 ] = 𝑟18 𝑟19 … 𝑟35 , 이미 entry가 있다면 해당 entry가 사전 순으로 더 빠르므로 넘어간다.)
- 𝑟0~𝑟17에 대해 사전 순으로 순회를 돌면서, 𝑓𝑖(𝑟0, 𝑟1, … , 𝑟17)를 구한 뒤 map에 entry가 있는지 확인한다.
- entry가 있다면 𝑟0~𝑟17와 map[𝑓𝑖(𝑟0, 𝑟1, … , 𝑟17)]을 이어 붙인 것이 답이다.
- 답이 존재한다면 𝑟𝑖 = 𝑓𝑖(𝑟0, 𝑟1, … , 𝑟17)⨂𝑓𝑖
′
𝑟18, 𝑟19, … , 𝑟35 이므로 𝑟𝑖 ⨂ 𝑓𝑖
′
𝑟18, 𝑟19, … , 𝑟35 = 𝑓𝑖(𝑟0, 𝑟1, … , 𝑟17)여야 함에 유의
한다.
- 시간 소요는 218
log 218
이다. (map insert/access가 O log 𝑁 이므로)
24. POSTECH Programming Contest
- 새로운 그래프를 정의하자. 정점 (v, d)는 원래 그래프의 정점 v까지 도달하는데 경로 상의 Bebe 수가 d마리임을
의미한다.
- 원래 그래프는 정점 a와 정점 b를 잇는 (c, d) 가중치를 가지는 간선들로 구성된다.
- 이를 새로운 그래프에서는 0≤p≤1000-d인 정수 p에 대해 정점 (a, p)와 정점 (b, p+d)를 잇는 가중치 c의 간선으
로 바꾼다.
- 물론 (b, p)와 (a, p+d)도 가중치 c로 이어준다.
I - Kaka & Bebe
Kaka & Bebe
25. POSTECH Programming Contest
Kaka & Bebe
- 이 그래프에서 정점 (0, 0)으로부터 시작하는 다익스트라 알고리즘을 시행하자.
- 이로부터 정점 (N-1, 0)부터 (N-1, 1000)까지 해당 정점까지 도달하는데 걸린 최소 c의 합이 나오게 된다.
- (N-1, i) 번 정점까지 도달하는데 걸린 최소 c의 합이 C_i일 때, i * C_i의 최소값을 구하면 문제의 정답이다.
- 새로운 그래프의 정점의 개수는 1000N개, 간선의 개수는 대략 1000M개이다.
- 다익스트라 알고리즘은 정점 V개 간선 E개인 그래프에 대해 O(E + VlogV)의 시간복잡도를 가지므로 시간 내로 답
이 나온다.