Koala - 9기/기초 알고리즘 스터디
[백준] #2828 사과 담기 게임
future0610
2023. 1. 22. 02:12
문제
Algorithm
먼저 상자의 크기가 1일 경우를 살펴보자. 사과가 처음 떨어질 때 상자의 이동거리는 상자의 처음 위치와 사과의 위치의 차이이다. 이후로는 현재 사과의 위치와 다음 사과의 위치의 차이가 상자의 이 구간에서의 이동거리가 될 것이다. 모든 구간에서의 이동거리의 합이 답이 될 것이다.
하지만 상자의 크기가 1보다 클 경우에는 상자의 최소 이동거리를 이렇게 구할 수 없다. 먼저 상자의 좌우 각각을 기준으로 더 작은 값이 나오는 쪽을 총 이동거리에 더해간다. $t$시간에서 상자의 가장 왼쪽 부분의 위치, 가장 오른쪽 부분의 위치, 사과의 위치를 각각 $a_t,\ L_t,\ R_t$라 하자. 상자의 크기는 $M$이므로 항상 $R_t = L_t + M$의 관계가 성립한다. 상자의 처음 위치는 $L_t = 0, R_t = M$이다. 이제 $|a_t - L_t|$와 $|a_t - R_t|$를 비교하여 더 작은 쪽을 총 이동거리에 더한다. 이후 $|a_t - L_t|>|a_t - R_t|$라면 $R_{t+1}=a_t,\ L_{t+1}=a_t-M+1$으로 갱신되고 $|a_t - L_t|<|a_t - R_t|$라면 $L_{t+1}=a_t,\ R{t+1}=a_t + M-1$이다. 하지만 $L_t\leq a_{t+1}\leq R_t$인 경우에는 사과의 위치만 갱신하고 이동거리도 갱신되지 않는다.
Code
input = __import__('sys').stdin.readline
N, M = map(int, input().split())
J = int(input())
apple = []
for _ in range(J):
apple.append(int(input()))
distance = 0
B = [1, M] # [L_t, R_t], L_1=1, R_1=M
for a in apple:
if B[0] <= a <= B[1]:
continue
else:
d1 = abs(a - B[0])
d2 = abs(a - B[1])
if d1 < d2:
distance += d1
B[0] = a
B[1] = a + M - 1
else:
distance += d2
B[0] = a - M + 1
B[1] = a
print(distance)