문제
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)
'Koala - 9기 > 기초 알고리즘 스터디' 카테고리의 다른 글
[백준/python] 14724 관리자는 누구? (0) | 2023.01.22 |
---|---|
[백준/C++] 1673 치킨 쿠폰 (0) | 2023.01.22 |
[백준/python] 1181 단어 정렬 (0) | 2023.01.21 |
[백준/python] 6502 동혁피자 (0) | 2023.01.21 |
[백준/python] 1302 베스트셀러 (0) | 2023.01.21 |