Algorithm & Problem Solving/그리디 알고리즘(Greedy)

[백준 19639] 배틀로얄 (Python)

baby_ohgu 2021. 2. 5. 20:59

www.acmicpc.net/problem/19639

 

19639번: 배틀로얄

첫 번째 줄에 X, Y, M (0 ≤ X, Y ≤ 100,000, 2 ≤ M ≤ 100,000)이 주어진다. M은 짝수다. 다음 X개의 줄에는 i번째 사람과 싸웠을 때 잃게 되는 체력이 주어진다. 이 수는 0 이상 M / 2 이하의 정수이다.

www.acmicpc.net

 

문제풀이

X, Y, M : 입력값

damage : 싸웠을 때 잃게 되는 체력

heal : 아이템을 먹었을 때 얻게 되는 체력

max_M : 초기 M

 

현재 체력(M) 이 초기 M (max_M) // 2 이하일 경우 포션을 먹고, max_M // 2 초과일 경우 적들과 싸우는 방식의 그리디 알고리즘으로 해결할 수 있다.

 

1. 현재 M 값 확인하기

- M <= max_M // 2 일 경우, 남아있는 아이템이 있으면 아이템 먹고 체력 회복하기

- M > max_M // 2 일 경우, 남아있는 적이 있으면 적과 싸우고 체력 감소하기

 

2. 적들과 모두 싸우고 아이템이 남아있는 경우 확인하기

- 아이템이 남아 있으면 모두 먹어야 하므로 남아있는 아이템 모두 먹기

 

코드

import sys

if __name__ == '__main__':
    X, Y, M = map(int, sys.stdin.readline().split())
    damage, heal = [], []
    for _ in range(X): damage.append(int(sys.stdin.readline()))
    for _ in range(Y): heal.append(int(sys.stdin.readline()))

    if M + sum(heal) <= sum(damage):
        print(0)
        exit(0)
    ans = []
    max_M = M
    d_idx, h_idx = 0, 0
    for _ in range(X + Y):
        if M > max_M // 2 and len(damage) > 0:
            M -= damage[d_idx]
            d_idx += 1
            ans.append(-d_idx)
        elif M <= max_M // 2 and len(heal) > 0:
            M += heal[h_idx]
            h_idx += 1
            ans.append(h_idx)

        if d_idx == len(damage) and h_idx != len(heal):
            while h_idx < len(heal):
                M += heal[h_idx]
                h_idx += 1
                ans.append(h_idx)
            break
    print('\n'.join(map(str, ans)) if len(ans) == X + Y else 0)

 

결과

 

문제풀이나 코드에서 이상한 부분 지적은 언제나 환영합니다!