2021. 9. 5. 21:06ㆍ알고리즘/이진탐색
문제
https://www.acmicpc.net/problem/16434문제 정의
용사는 공주를 구하기 위해 무시무시한 용이 있는 던전으로 향하기로 하였습니다. 우선 용사는 용사 자신과 던전을 분석하였습니다.
용사에게는 세 종류의 능력치가 있습니다.
던전은 총 N개의 방으로 이루어져 있고 i번째 방을 통해서만 i+1번째 방으로 이동 할 수 있습니다. 방에는 포션이 있거나 몬스터가 있는데 몬스터가 있을 경우 몬스터를 쓰러트려야지 다음방으로 이동 할 수 있습니다. N번째 방에는 공주와 용이 있고, 용을 무찌르면 공주를 구할 수 있습니다.
몬스터가 있는 방에 올 경우 다음과 같이 전투가 진행됩니다.
포션이 있는 방에 올 경우 포션을 마셔서 현재 용사의 생명력 HCurHP가 일정량 회복되고 공격력 HATK도 일정량만큼 증가됩니다. 회복된 생명력이 최대 생명력 HMaxHP보다 큰 경우 용사의 현재 생명력 HCurHP가 최대 생명력 HMaxHP와 같아집니다.
용사는 던전으로 향하기 전에 만반의 준비를 하고 있습니다. 용사는 수련을 하면 최대 생명력 HMaxHP를 늘릴 수 있는데 얼마나 수련해야 할지 고민입니다.
용사는 N번 방에 있는 용을 쓰러트리기 위한 최소의 HMaxHP를 여러분이 계산해주면 좋겠다고 합니다.
입력
첫 번째 줄에 방의 개수 N (1 ≤ N ≤ 123,456) 과 용사의 초기 공격력 HATK (1 ≤ HATK ≤ 1,000,000) 가 주어집니다.
i+1번째 줄엔 i번째 방의 정보를 나타내는 세개의 정수 ti, ai, hi (ti ∈ {1, 2}, 1 ≤ ai, hi ≤ 1,000,000) 가 주어집니다.
ti가 1인 경우 공격력이 ai이고 생명력이 hi인 몬스터가 있음을 나타내고, ti가 2인 경우 용사의 공격력 HATK를 ai만큼 증가시켜주고 용사의 현재 생명력 HCurHP를 hi만큼 회복시켜주는 포션이 있음을 나타냅니다.
출력
용사가 N번째 방에 있는 용을 쓰러트리기 위한 최소의 HMaxHP를 출력합니다.
예제 입력 1
3 3 1 1 20 2 3 10 1 3 100
예제 출력 1
49
접근 방법
- 용사의 max_hp를 기준으로 이진탐색을 진행한다. 초기 start는 1, end는 (1000000 ** 2) x n로 설정한다.
- 그 뒤 N개의 방에 대해서 탐색을 진행하며 용사가 던전을 클리어하면 값을 저장해가며 클리어할 수 있는 최소 max_hp를 구한다.
코드
# https://www.acmicpc.net/problem/16434
# 접근 방법
# 용사의 max_hp를 기준으로 이진탐색을 진행한다. 초기 start는 1, end는 (1000000 ** 2) x n로 설정한다.
# 그 뒤 N개의 방에 대해서 탐색을 진행하며 용사가 던전을 클리어하면 값을 저장해가며 클리어할 수 있는 최소 max_hp를 구한다.
def battle(cur_hp, a, h, atk):
number_of_turns = h // atk - 1
if h % atk:
number_of_turns += 1
cur_hp = max(cur_hp - (a * number_of_turns), 0)
return cur_hp
def dungeon(hp, atk):
cur_hp = hp
for t, a, h in array:
if t == 1:
cur_hp = battle(cur_hp, a, h, atk)
if not cur_hp:
return False
else:
atk += a
cur_hp = min(cur_hp + h, hp)
return True
import sys
n, atk = map(int, sys.stdin.readline().split())
array = []
max_a = 0
max_h = 0
for _ in range(n):
t, a, h = map(int, sys.stdin.readline().split())
if t == 1:
max_a = max(a, max_a)
max_h = max(h, max_h)
array.append([t, a, h])
start = 1
end = max_a * max_h * n
max_hp = end
while start <= end:
mid = (start+end) // 2
if dungeon(mid, atk):
end = mid - 1
max_hp = min(max_hp, mid)
else:
start = mid + 1
print(max_hp)
'알고리즘 > 이진탐색' 카테고리의 다른 글
백준 온라인 저지, 이진탐색 / 3649번: 로봇프로젝트 (파이썬 / 백준 골드문제) (0) | 2021.09.15 |
---|---|
백준 온라인 저지, 이진탐색 / 8983번: 사냥꾼 (파이썬 / 백준 골드문제) (0) | 2021.09.05 |
백준 온라인 저지, 이진탐색 / 2343번: 기타레슨 (파이썬) (0) | 2021.09.05 |
백준 온라인 저지, 이진탐색 / 7795번: 먹을 것인가 먹힐 것인가 (파이썬 / 백준 골드문제) (0) | 2021.09.01 |
백준 온라인 저지, 이진탐색 / 1365번: 꼬인전깃줄 (파이썬 / 백준 골드문제) (0) | 2021.09.01 |