Div2A. Split it!
앞 $K$글자와 뒤 $K$글자를 뒤집은 것이 같고, 가운데 다른 문자열이 들어갈 수 있는지 판별하면 됩니다.
1 |
|
Div2B. Max and Mex
관찰 1. 만약 초기 multiset의 mex값이 $N$이라면 연산을 할 때마다 set의 크기가 증가합니다.
관찰 2. 그렇지 않다면 set의 크기는 $O(N)$번 증가합니다.
관찰 1은 자명하고, 관찰 2는 계속 크기가 증가하다가 어느 순간 기존에 존재하던 원소에 의해 막힌다는 것을 보이면 됩니다.
그러므로 $mex(a) = N$이면 $N + K$을 출력하고, 그렇지 않다면 문제에 나와있는 과정을 시뮬레이션하면 됩니다.
1 |
|
Div2C/Div1A. Diamond Miner
$x, y$좌표에 각각 절댓값을 취해도 답이 바뀌지 않는다는 것은 쉽게 알 수 있습니다. 일반성을 잃지 않고, $x \geq 0, y \geq 0$이라고 합시다. 어떤 매칭이 교차한다면 교차하지 않도록 풀어주는 것이 항상 이득이라는 것을 증명할 수 있습니다.
그러므로 $x, y$좌표에 각각 절댓값을 취하고 정렬한 뒤, 순서대로 매칭해주면 됩니다.
1 |
|
Div2D/Div1B. Let’s Go Hiking
정신나간 CaseWork 문제
설명의 편의를 위해 $x, y$의 시작 지점을 각각 $x_0, y_0$이라고 합시다. 게임의 형태를 4가지 케이스로 분류할 수 있습니다.
- case 1) y0 < x0 && y는 왼쪽으로 이동 (서로 거리가 멀어짐)
- case 2) y0 > x0 && y는 오른쪽으로 이동 (서로 거리가 멀어짐)
- case 3) y0 < x0 && y는 오른쪽으로 이동 (서로 거리가 가까워짐)
- case 4) y0 > x0 && y는 왼쪽으로 이동 (서로 거리가 가까워짐)
4가지 케이스를 고려하면서, 어떤 $x_0$이 이기는 위치인지 Sub-linear Time에 판별하는 것이 목표입니다.
배열 6개를 정의합시다. 이 배열들은 투포인터(or 슬라이딩 윈도우) 느낌으로 $O(N)$에 전처리할 수 있습니다.
- DecL[i] : i에서 시작해서 왼쪽으로 내려갈 수 있는 마지막 위치 (Qingshan이 i에서 시작해 갈 수 있는 가장 왼쪽)
- DecR[i] : i에서 시작해서 오른쪽으로 내려갈 수 있는 마지막 위치
- IncL[i] : i에서 시작해서 왼쪽으로 올라갈 수 있는 마지막 위치 (Daniel이 i에서 시작해 갈 수 있는 가장 왼쪽)
- IncR[i] : i에서 시작해서 오른쪽으로 올라갈 수 있는 마지막 위치
- CntL[i] : i - DecL[i] (i에서 시작해서 Qingshan이 왼쪽으로 이동할 수 있는 최대 거리)
- CntR[i] : DecR[i] - i (i에서 시작해서 Qingshan이 오른쪽으로 이동할 수 있는 최대 거리)
case 1은 $y < x_0$인 모든 $y$에 대해, $y - IncL[y] < \max(CntL[x_0], CntR[x_0])$인지 확인하면 됩니다.
case 2는 $y > x_0$인 모든 $y$에 대해, $IncR[y] - y < \max(CntL[x_0], CntR[x_0])$인지 확인하면 됩니다.
Prefix/Suffix Maximum을 관리하면 $O(1)$에 처리할 수 있고, Maximum Segment Tree를 이용하면 $O(\log N)$에 처리할 수 있습니다.
case 3, 4도 비슷하게 처리할 수 있으면 좋았겠지만, 아쉽게도 두 사람이 모두 도달할 수 있는 위치가 존재하기 때문에 다양한 경우가 생겨 이 풀이를 그대로 적용할 수 없습니다. case 3부터 봅시다. 5가지 케이스로 나눌 수 있습니다.
- case 3-1) 구간이 만남 + x는 왼쪽으로 이동
- case 3-1-1) x0과 y0의 거리는 짝수
- case 3-1-2) x0과 y0의 거리는 홀수
- case 3-2) 구간이 만남 + x는 오른쪽으로 이동
- case 3-3) 구간 안 만남 + x는 왼쪽으로 이동
- case 3-4) 구간 안 만남 + x는 오른쪽으로 이동
case 3-1-1에서 $x_0$은 무조건 이기는 위치가 됩니다. 비슷하게, 3-1-2에서는 무조건 지는 위치입니다.
case 3-2는 $y < x_0$인 모든 $y$에 대해, $IncR[y] - y < CntR[x_0]$인지 확인하면 됩니다.
case 3-3은 $y < x_0$인 모든 $y$에 대해, $IncR[y] - y < CntL[x_0]$인지 확인하면 됩니다.
case 3-4는 case 3-2와 동일하게 처리해도 됩니다.
그러므로,
구간이 만나는 $y_0$에 대해서는 거리가 짝수이면 승리, 홀수이면 오른쪽으로 이동해서 $IncR[y_0] - y_0 < CntR[x_0]$인지 확인하면 됩니다.
구간이 만나지 않는 $y_0$에 대해서는 $IncR[y_0] - y_0 < \max(CntL[x_0], CntR[x_0])$인지 확인하면 됩니다.
이때 구간이 만나는 $y_0$의 범위는 $[DecL[x_0], x_0)$이며, 구간이 만나지 않는 $y_0$의 범위는 $[1, DecL[x_0])$입니다.
비슷하게 case 4도 5가지의 케이스로 나누어서 해결할 수 있습니다.
구간이 만나는 $y_0$에 대해서는 거리가 짝수이면 승리, 홀수이면 왼쪽으로 이동해서 $y_0 - IncL[y_0] < CntL[x_0]$인지 확인하면 됩니다.
구간이 만나지 않는 $y_0$에 대해서는 $y_0 - IncL[y_0] < \max(CntL[x_0], CntR[x_0])$인지 확인하면 됩니다.
이때 구간이 만나는 $y_0$의 범위는 $(x_0, DecR[x_0]]$이며, 구간이 만나지 않는 $y_0$의 범위는 $(Dec[x_0], N]$입니다.
case 3, 4는 Maximum Segment Tree를 이용해 $O(\log N)$에 해결할 수 있습니다.
총 12가지 케이스를 모두 고려해주면 투포인터와 세그먼트 트리를 이용한 $O(N \log N)$ 풀이를 얻을 수 있고, 그대로 코딩하면 문제를 해결할 수 있습니다.
이런 환상적인 문제를 세팅한 Setter와 Tester분들께 존경을 표합니다…
1 |
|
Div2E/Div1C. Garden of Sun
대회 중에는 Manhattan MST로 접근했다가 망했습니다. 대회 끝나고 Aeren님께 풀이를 들었습니다.
$i \mod 3 \equiv 0$인 행을 모두 칠하고, 이렇게 칠한 부분을 “줄기”라고 합시다.
$i \mod 3 = 1\ or\ 2$인 행에 'X'
가 있을텐데, 이런 칸들은 “줄기”에서 “가지”를 뻗어서 연결하면 됩니다.
혹시 $3K$번째 행과 $3K+3$번째 행을 연결하는 가지를 뻗지 못했다면 임의로 한 지점을 잡아서 연결하면 됩니다.
$N$이 3의 배수인 경우를 조심합시다.
1 |
|