μ•Œκ³ λ¦¬μ¦˜/Greedy

[λ°±μ€€ 1461 πŸ₯‡] λ„μ„œκ΄€

1eehyunji 2023. 8. 28. 00:55

문제

μ„Έμ€€μ΄λŠ” λ„μ„œκ΄€μ—μ„œ μΌν•œλ‹€. λ„μ„œκ΄€μ˜ κ°œλ°©μ‹œκ°„μ΄ λλ‚˜μ„œ μ„Έμ€€μ΄λŠ” μ‚¬λžŒλ“€μ΄ 마ꡬ 놓은 책을 λ‹€μ‹œ κ°€μ Έλ‹€ 놓아야 ν•œλ‹€. μ„Έμ€€μ΄λŠ” ν˜„μž¬ 0에 있고, μ‚¬λžŒλ“€μ΄ 마ꡬ 놓은 책도 μ „λΆ€ 0에 μžˆλ‹€. 각 μ±…λ“€μ˜ μ›λž˜ μœ„μΉ˜κ°€ μ£Όμ–΄μ§ˆ λ•Œ, 책을 λͺ¨λ‘ μ œμžλ¦¬μ— λ†”λ‘˜ λ•Œ λ“œλŠ” μ΅œμ†Œ 걸음 수λ₯Ό κ³„μ‚°ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. μ„Έμ€€μ΄λŠ” ν•œ κ±ΈμŒμ— μ’Œν‘œ 1μΉΈμ”© κ°€λ©°, μ±…μ˜ μ›λž˜ μœ„μΉ˜λŠ” μ •μˆ˜ μ’Œν‘œμ΄λ‹€. 책을 λͺ¨λ‘ μ œμžλ¦¬μ— 놔둔 ν›„μ—λŠ” λ‹€μ‹œ 0으둜 λŒμ•„μ˜¬ ν•„μš”λŠ” μ—†λ‹€. 그리고 μ„Έμ€€μ΄λŠ” ν•œ λ²ˆμ— μ΅œλŒ€ Mꢌ의 책을 λ“€ 수 μžˆλ‹€.

μž…λ ₯

첫째 쀄에 μ±…μ˜ 개수 Nκ³Ό, 세쀀이가 ν•œ λ²ˆμ— λ“€ 수 μžˆλŠ” μ±…μ˜ 개수 M이 μ£Όμ–΄μ§„λ‹€. λ‘˜μ§Έ μ€„μ—λŠ” μ±…μ˜ μœ„μΉ˜κ°€ μ£Όμ–΄μ§„λ‹€. Nκ³Ό M은 50보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. μ±…μ˜ μœ„μΉ˜λŠ” 0이 μ•„λ‹ˆλ©°, μ ˆλŒ“값은 10,000보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€.

좜λ ₯

첫째 쀄에 정닡을 좜λ ₯ν•œλ‹€.

문제 풀이

import sys
from collections import deque

n,m=map(int, sys.stdin.readline().strip().split(' '))
books=list(map(int, sys.stdin.readline().strip().split(' ')))

books.sort()

# μ ˆλŒ“κ°’μ΄ κ°€μž₯ 큰 μΈλ±μŠ€κ°€ μ–‘μˆ˜μΈμ§€ μŒμˆ˜μΈμ§€?
maxidx=0
if abs(books[-1])>abs(books[0]):
    maxidx=-1

plus=deque()
minus=deque()
for book in books:
    if book>0:
        plus.append(book)
    else:
        minus.append(book)

# 음수 μ˜μ—­ κΈ°μ€€ μ΅œμ†Œ 발자ꡭ κ΅¬ν•˜κΈ°
ans_minus=0
mod_minus=len(minus)%m
step=0
if minus and len(minus)<=m:
    if minus[0]==books[maxidx]:
        ans_minus+=abs(minus[0])
    else:
        ans_minus+=abs(minus[0])*2
else:
    if mod_minus != 0:
        for _ in range(mod_minus):
            step = minus.pop()
        ans_minus += (abs(step) * 2)

    while minus:
        if len(minus) <= m:
            if minus[0] == books[maxidx]:
                ans_minus += abs(minus[0])
                break
        for _ in range(m):
            step = minus.pop()
        ans_minus += (abs(step) * 2)

# μ–‘μˆ˜ μ˜μ—­ κΈ°μ€€ μ΅œμ†Œ 발자ꡭ κ΅¬ν•˜κΈ°
ans_plus=0
mod_plus=len(plus)%m
step=0
if plus and len(plus)<=m:
    if plus[-1]==books[maxidx]:
        ans_plus+=plus[-1]
    else:
        ans_plus+=plus[-1]*2
else:
    if mod_plus != 0:
        for _ in range(mod_plus):
            step = plus.popleft()
        ans_plus += (step * 2)

    while plus:
        if len(plus) <= m:
            if plus[-1] == books[maxidx]:
                ans_plus += plus[-1]
                break
        for _ in range(m):
            step = plus.popleft()
        ans_plus += (step * 2)

print(ans_plus+ans_minus)
  • 책을 λͺ¨λ‘ μ œμžλ¦¬μ— λ‘” 이후에 λ‹€μ‹œ 0으둜 λŒμ•„μ˜¬ ν•„μš”κ°€ μ—†μœΌλ―€λ‘œ, μ ˆλŒ“κ°’μ΄ κ°€μž₯ 큰 μœ„μΉ˜μ— μžˆλŠ” 책은 λ§ˆμ§€λ§‰μ— μ²˜λ¦¬ν•΄μ„œ λ‹€μ‹œ λŒμ•„μ˜€λŠ” κ±ΈμŒμ€ μΆ”κ°€ν•΄μ£Όμ§€ μ•Šμ•„μ•Ό ν•œλ‹€.
  • μš°μ„  μž…λ ₯받은 μ±…λ“€μ˜ μœ„μΉ˜λ₯Ό μ •λ ¬ν•΄μ€€λ‹€.
  • μ ˆλŒ“κ°’μ΄ 큰 μˆ˜κ°€ κ°€μž₯ μ™Όμͺ½ μˆ˜μΈμ§€, κ°€μž₯ 였λ₯Έμͺ½ μˆ˜μΈμ§€ λΉ„κ΅ν•˜κ³ , κ²°κ³Όλ₯Ό maxidx에 0(μ™Όμͺ½) λ˜λŠ” -1(였λ₯Έμͺ½)으둜 μ €μž₯ν•΄μ€€λ‹€.
  • λ§ˆμ§€λ§‰ 책을 κ°€μ Έλ‹€ λ‘” 경우λ₯Ό μ œμ™Έν•˜κ³  책을 κ°€μ Έλ‹€ 놓고 λ‹€μ‹œ 0으둜 λŒμ•„μ™€μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— 0을 μ€‘μ‹¬μœΌλ‘œ μˆ˜λ“€μ„ μ‚΄νŽ΄λ³΄λ©΄μ„œ 음수인 값듀을 λ”°λ‘œ μ €μž₯ν•˜κ³ , μ–‘μˆ˜μΈ 값듀을 λ”°λ‘œ μ €μž₯ν•΄μ„œ 각각 μ΅œμ†Œ κ±ΈμŒμ„ κ΅¬ν•˜κ³  λ”ν•˜λ©΄ λœλ‹€.
  • μŒμˆ˜μ™€ μ–‘μˆ˜ 각각의 κ°œμˆ˜κ°€ m으둜 λ‚˜λˆ μ§€μ§€ μ•ŠλŠ” 경우, m으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ§ŒνΌμ€ κ°€μž₯ 거리가 κ°€κΉŒμš΄ μˆœμ„œλŒ€λ‘œ μ²˜λ¦¬ν•΄μ£Όκ³ , 남은 책듀을 ν•œ λ²ˆμ— μ²˜λ¦¬ν•  수 μžˆλŠ” mκΆŒμ”© μ œκ±°ν•΄μ£Όλ©΄μ„œ λͺ‡ κ±ΈμŒμ„ 닀녀와야 ν•˜λŠ”μ§€ κ³„μ‚°ν•œλ‹€.

문제 예제 1,2,3λ²ˆμ„ κΈ°μ€€μœΌλ‘œ μ˜ˆμ‹œλ₯Ό 듀어보면 λ‹€μŒκ³Ό κ°™λ‹€.