<think>우리는 이진 탐색을 사용하여 숙련도(level)의 최솟값을 찾을 수 있습니다.
조건:
diff <= level 이면, time_cur 만큼의 시간이 소요.
diff > level 이면, (diff - level) 번 틀리고, 각 틀릴 때마다 (time_cur + time_prev)의 시간이 소요되고, 마지막에 time_cur이 소요됨.
따라서 총 시간 = (diff - level) * (time_cur + time_prev) + time_cur
하지만 주의: 첫 번째 퍼즐의 경우 이전 퍼즐이 없습니다. 문제에서 "이전 퍼즐"은 두 번째 퍼즐부터 적용됩니다.
따라서 첫 번째 퍼즐은 어떻게 처리해야 할까?
문제 설명에 따르면, 첫 번째 퍼즐을 풀 때 이전 퍼즐이 없습니다.
조건을 보면:
diff > level 인 경우, 틀릴 때마다 time_cur (현재 퍼즐의 시간)과 time_prev (이전 퍼즐의 시간)을 소모하며 이전 퍼즐을 다시 풀고 와야 한다.
그러나 첫 번째 퍼즐에는 이전 퍼즐이 없으므로, 이전 퍼즐을 다시 풀 수 없습니다.
문제를 다시 읽어보면, 예시에서 첫 번째 퍼즐에 대한 언급이 없습니다.
입력은 배열로 주어지므로, 첫 번째 퍼즐은 어떻게 처리해야 할까?
문제의 조건:
"이전 퍼즐을 다시 풀 때는 이전 퍼즐의 난이도에 상관없이 틀리지 않습니다."
하지만 첫 번째 퍼즐은 이전 퍼즐이 없기 때문에, 첫 번째 퍼즐을 풀 때는 이전 퍼즐을 다시 풀 수 없습니다.
따라서 첫 번째 퍼즐에 대해서는 diff > level 인 경우에도 이전 퍼즐을 다시 풀 수 없다는 점을 고려해야 합니다.
그러나 문제에서 첫 번째 퍼즐에 대한 특별한 규정을 언급하지 않았습니다.
예시에서는 첫 번째 퍼즐이 아닌 경우를 설명하고 있습니다.
다시 문제를 보면, "현재 퍼즐"과 "이전 퍼즐"이라는 용어를 사용하고 있으므로,
첫 번째 퍼즐은 이전 퍼즐이 없으므로, 첫 번째 퍼즐을 풀 때는 오직 현재 퍼즐의 난이도와 숙련도만 비교해야 합니다.
문제의 조건을 첫 번째 퍼즐에 적용해보면:
diff ≤ level: time_cur 만큼 시간 소요.
diff > level: (diff - level) 번 틀리게 되지만, 이전 퍼즐이 없으므로 time_prev를 사용할 수 없습니다.
문제에서 이전 퍼즐의 소요 시간(time_prev)을 사용하라고 했지만, 첫 번째 퍼즐에서는 time_prev가 존재하지 않습니다.
따라서, 첫 번째 퍼즐에 대해서는 이전 퍼즐을 다시 풀 수 없으므로, 틀릴 때마다 추가적인 time_prev를 사용하지 못할 것입니다.
하지만 문제의 예시에서는 첫 번째 퍼즐이 아닌 경우를 설명하고 있습니다.
우리는 첫 번째 퍼즐을 어떻게 처리해야 할지 문제의 조건에서 명시적으로 알 수 없습니다.
이에 대한 해석이 필요합니다.
문제의 조건을 보면, "이전 퍼즐을 다시 풀고 와야 합니다" 라고 했으므로,
첫 번째 퍼즐에서는 이전 퍼즐이 없기 때문에 틀렸을 때 이전 퍼즐을 다시 풀 수 없습니다.
따라서 첫 번째 퍼즐은 무조건 한 번에 맞춰야 한다고 해석할 수 있습니다.
또는, 첫 번째 퍼즐에서는 이전 퍼즐이 없으므로 time_prev를 0으로 간주할 수 있을까요?
문제에서 주어진 매개변수는:
diffs: 퍼즐의 난이도 배열 (길이 n)
times: 퍼즐의 소요 시간 배열 (길이 n)
limit: 전체 제한 시간
그리고 첫 번째 퍼즐의 이전 퍼즐은 존재하지 않습니다.
문제를 해결하기 위해 다음과 같이 가정합니다:
첫 번째 퍼즐 (i=0)을 풀 때:
if diff[0] <= level: 시간 = times[0]
else:
# diff[0] > level 인 경우, 틀린 횟수 = diff[0] - level
# 하지만 이전 퍼즐이 없으므로, time_prev를 0으로 생각해야 할까?
# 문제에서 "이전 퍼즐의 소요 시간"을 사용하라고 했지만, 없으므로 0으로 처리하면?
# 그러면 틀릴 때마다 (times[0] + 0) = times[0]이 소요되고, 마지막에 times[0]이 소요됨.
# 따라서 총 시간 = (diff[0]-level)*times[0] + times[0] = (diff[0]-level+1)*times[0]
두 번째 퍼즐부터 (i>=1):
if diff[i] <= level: 시간 = times[i]
else: 시간 = (diff[i]-level)*(times[i] + times[i-1]) + times[i]
하지만 예시에서 첫 번째 퍼즐에 대한 언급이 없으므로, 이 가정을 검증할 수 없습니다.
그러나 문제의 예시 입력이 주어지지 않았으므로, 문제의 설명에 따라 일반화해야 합니다.
문제를 출제한 의도로 보아, 첫 번째 퍼즐에 대해서는 이전 퍼즐이 없으므로,
틀렸을 때 이전 퍼즐을 다시 풀지 않아도 된다고 하면 안됩니다.
오히려 첫 번째 퍼즐을 틀리면 이전 퍼즐이 없기 때문에 다시 풀 수 없으므로,
첫 번째 퍼즐은 무조건 한 번에 맞춰야 한다고 생각할 수 있습니다.
하지만 문제에서 숙련도를 최소화하면서 제한 시간 내에 풀어야 하므로,
첫 번째 퍼즐도 숙련도가 낮으면 틀릴 수 있다고 가정해야 합니다.
문제의 조건을 재해석:
"퍼즐을 틀릴 때마다, 만큼의 시간을 사용하며, 추가로 만큼의 시간을 사용해 이전 퍼즐을 다시 풀고 와야 합니다."
-> 이전 퍼즐이 없으면, "이전 퍼즐을 다시 풀고 오는" 과정이 불가능합니다.
따라서 첫 번째 퍼즐은 틀리면 안 됩니다.
즉, 첫 번째 퍼즐은 숙련도가 난이도보다 높아서 틀리지 않아야 합니다.
하지만 숙련도의 최솟값을 구하는 문제이므로, 첫 번째 퍼즐의 난이도가 높을 경우 숙련도를 높여야 합니다.
하지만 이렇게 되면 첫 번째 퍼즐은 무조건 diff[0] <= level 이어야 합니다.
만약 level이 diff[0]보다 작으면 첫 번째 퍼즐을 풀 수 없게 됩니다.
그러나 문제의 조건에서는 숙련도를 선택할 수 있고, 우리가 구하려는 숙련도의 최솟값이므로,
첫 번째 퍼즐의 난이도 diff[0]보다 적어도 level이 diff[0] 이상이어야 합니다.
하지만 두 번째 퍼즐부터는 이전 퍼즐이 있으므로 level이 더 낮아도 틀릴 수 있습니다.
따라서 첫 번째 퍼즐에 대해서는:
무조건 diff[0] <= level 이어야 하므로, 시간은 times[0] 만 소요됩니다.
이 가정을 바탕으로 하면, 첫 번째 퍼즐은 항상 한 번에 풀립니다.
하지만 문제에서 주어진 예시는 첫 번째 퍼즐이 아닌 경우를 설명하고 있으므로,
이렇게 해석하는 것이 합리적입니다.
따라서 전체 퍼즐을 푸는 총 시간:
time_total = time0 + time1 + ... + time_{n-1}
where
time0 = times[0] (첫 번째 퍼즐은 무조건 한 번에 풀리므로)
for i from 1 to n-1:
if diffs[i] <= level:
time_i = times[i]
else:
time_i = (diffs[i] - level) * (times[i] + times[i-1]) + times[i]
이제 우리는 level의 최솟값을 찾아야 합니다.
level은 적어도 첫 번째 퍼즐의 난이도 diff[0] 이상이어야 합니다.
level의 하한: 1 (양의 정수)
level의 상한: max(diffs) (모든 퍼즐의 난이도 중 최댓값)
-> 왜냐하면 level이 max(diffs)가 되면 모든 퍼즐에 대해 diff[i] <= level이 성립하므로,
총 시간은 단순히 times 배열의 합이 됩니다.
따라서 level의 범위: [1, max_diff] (max_diff = max(diffs))
하지만 첫 번째 퍼즐을 고려하면 level은 최소한 diff[0] 이상이어야 합니다.
그러나 level이 diff[0]보다 작을 수는 없습니다. (첫 번째 퍼즐을 풀 수 없으므로)
따라서 level의 하한: max(1, diff[0])?
하지만 두 번째 퍼즐부터는 level이 작아도 풀 수 있으므로,
첫 번째 퍼즐을 풀기 위해 level >= diff[0]이 필요합니다.
그러므로 level의 범위: [diff[0], max_diff]
단, diff[0]이 1보다 작을 수 없으므로 (양의 정수) [diff[0], max_diff]
하지만 만약 첫 번째 퍼즐의 난이도가 max_diff보다 클 수도 있습니다?
그런 경우는 없습니다. max_diff는 모든 난이도의 최댓값이므로, diff[0] <= max_diff입니다.
따라서 level을 diff[0]부터 max_diff까지 이진 탐색하면서,
총 시간이 limit 이하인지 확인합니다.
이진 탐색:
low = diff[0]
high = max_diff (max_diff = max(diffs))
while low <= high:
mid = (low+high)//2
total_time = calc_time(mid) # mid level로 계산한 총 시간
if total_time <= limit:
answer = mid
high = mid - 1 # 더 작은 level을 시도
else:
low = mid + 1
만약 [diff[0], max_diff] 범위 내에서 limit 이하를 만족하는 level이 없으면?
문제에서 제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값을 구하는 것이므로,
만약 이 범위에서 조건을 만족하는 level이 없으면, 더 큰 level을 시도해야 할까?
하지만 level이 max_diff보다 커봤자, max_diff일 때와 동일하게 동작합니다.
(level이 max_diff 이상이면 모든 퍼즐이 한 번에 풀리므로, 총 시간은 times의 합)
따라서 max_diff일 때 총 시간 = sum(times)
만약 sum(times) > limit 이면, 제한 시간 내에 풀 수 없는 경우가 됩니다.
문제의 return 조건:
제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값을 정수로 return.
만약 제한 시간 내에 풀 수 없다면? 문제에서 명시하지 않았으므로,
우리는 항상 제한 시간 내에 풀 수 있는 경우만 입력으로 주어진다고 가정할 수 없습니다.
문제 조건: "제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값" -> 만약 불가능하다면?
문제에 따르지 않았으므로, 일단은 가능한 입력만 주어진다고 가정하거나,
불가능한 경우 -1을 반환하는 등의 처리가 필요할 수 있습니다.
하지만 문제의 제한 사항을 보지 못했으므로,
일단은 이진 탐색을 시도하고, [diff[0], max_diff] 범위에서 조건을 만족하는 level이 없으면,
max_diff+1 이상의 level은 모두 max_diff일 때와 같은 총 시간을 가지므로,
max_diff일 때의 총 시간이 limit보다 크면 어떤 level로도 해결할 수 없습니다.
따라서,
if calc_time(max_diff) > limit:
return -1 # 또는 문제에 따라 다른 처리?
else:
이진 탐색을 통해 찾은 최소 level 반환
하지만 문제에서 "제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값"을 구하라고 했으므로,
제한 시간 내에 풀 수 없다면 명시하지 않았지만, 일반적으로는 -1을 반환하거나 에러를 반환할 수 있습니다.
문제의 매개변수 제한사항을 보지 못했으므로,
일단은 제한 시간 내에 풀 수 있는 입력만 주어진다고 가정하고 풀어보겠습니다.
(만약 그렇지 않다면, 문제에서 어떻게 처리할지 명시해야 합니다.)
하지만 문제의 예시가 없으므로, 우리는 가정을 해야 합니다.
결론:
1. level의 범위: [min_level, max_level]
min_level = min_possible = diff[0] (첫 번째 퍼즐을 풀기 위해)
max_level = max(diffs)
2. calc_time(level) 함수 구현:
total = times[0] # 첫 번째 퍼즐
for i in range(1, len(diffs)):
if diffs[i] <= level:
total += times[i]
else:
# 틀린 횟수 = diffs[i] - level
total += (diffs[i] - level) * (times[i] + times[i-1]) + times[i]
3. 이진 탐색을 수행.
4. 만약 max_level일 때의 총 시간이 limit보다 크면, -1 반환?
문제에서 제한 시간 내에 풀 수 없는 경우에 대한 처리를 명시하지 않았으므로,
실제 문제에서는 어떻게 할지 확인이 필요합니다.
여기서는 일단 -1을 반환하도록 하겠습니다.
하지만, level을 max_level보다 더 높인다고 해도 총 시간은 변하지 않습니다.
따라서 max_level일 때 총 시간이 limit보다 크면, 어떤 level로도 해결할 수 없습니다.
구현:
def solution(diffs, times, limit):
n = len(diffs)
if n == 0:
return 0 # 퍼즐이 없으면 level은 0? 하지만 level은 양의 정수이므로 1? 하지만 퍼즐이 없으면 0도 가능? -> 문제에서 양의 정수라고 했지만, 퍼즐이 없으면 의미가 없으므로 0 반환?
# 문제에서 퍼즐의 개수 n에 대한 언급이 없으므로, 빈 배열일 수 있습니다.
# 첫 번째 퍼즐: 무조건 times[0]이 소요된다.
# min_level = diffs[0] (첫 번째 퍼즐을 풀기 위해)
max_level = max(diffs)
# max_level일 때의 총 시간 계산 (모든 퍼즐이 한 번에 풀리는 경우)
total_max = sum(times)
if total_max > limit:
return -1 # 제한 시간 내에 풀 수 없음
# min_level: diffs[0] (이것보다 작으면 첫 퍼즐을 못 품)
low = diffs[0]
high = max_level
ans = max_level # 최소한 max_level은 만족하므로
while low <= high:
mid = (low + high) // 2
t = calc_time(diffs, times, mid)
if t <= limit:
ans = mid
high = mid - 1
else:
low = mid + 1
return ans
def calc_time(diffs, times, level):
total = times[0] # 첫 번째 퍼즐
n = len(diffs)
for i in range(1, n):
if diffs[i] <= level:
total += times[i]
else:
# 틀린 횟수 = diffs[i] - level
total += (diffs[i] - level) * (times[i] + times[i-1]) + times[i]
return total
그러나 이 코드는 첫 번째 퍼즐 이후의 퍼즐들만 고려하고, 첫 번째 퍼즐은 항상 times[0]을 사용합니다.
테스트 예시:
예시로 주어진 경우: diff=3, time_cur=2, time_prev=4, level=1 -> 14, level=2->8, level>=3->2
하지만 이 예시는 하나의 퍼즐에 대한 것이고, 두 번째 퍼즐이라고 가정해야 합니다.
따라서 diffs = [?, 3] 이고, times = [4,2] 라고 하면,
첫 번째 퍼즐: diff[0]=? (첫 번째 퍼즐의 난이도) -> 첫 번째 퍼즐은 4초가 걸리고,
두 번째 퍼즐:
level=1 -> 3>1 -> (3-1)*(2+4)+2 = 2*6+2 = 14
level=2 -> 3>2 -> (3-2)*6+2 = 8
level=3 -> 3<=3 -> 2
따라서 총 시간:
level=1: 4 + 14 = 18
level=2: 4+8=12
level=3: 4+2=6
만약 limit=10 이라면, level=2일 때 12>10 이므로 level=3이 최소 (6<=10) -> level=3
하지만 우리는 level의 최솟값을 구하는 것이므로, 첫 번째 퍼즐의 난이도가 첫 번째 퍼즐의 level 제약을 결정합니다.
여기서 첫 번째 퍼즐의 난이도가 무엇인지 모릅니다.
예시에서 첫 번째 퍼즐의 난이도는 주어지지 않았습니다.
따라서, 우리가 만든 함수는 첫 번째 퍼즐의 난이도가 diffs[0]으로 주어집니다.
예를 들어, 첫 번째 퍼즐의 난이도가 1이고, 두 번째 퍼즐의 난이도가 3,
첫 번째 퍼즐의 소요시간이 4, 두 번째가 2, limit=10 이라면,
level은 최소 1 (첫 번째 퍼즐의 난이도 1 이상) 이어야 합니다.
level=1: 총 시간 = 4 (첫 번째) + (3>1 -> (3-1)*(2+4)+2 = 14) -> 18 -> 18>10 -> 실패
level=2: 4 + (3>2 -> 8) = 12 -> 12>10 -> 실패
level=3: 4 + (3<=3 -> 2) = 6 -> 성공 -> 답 3
하지만 level=2일 때 첫 번째 퍼즐: diff[0]=1 <=2 -> 성공 (시간 4)
두 번째 퍼즐: diff[1]=3>2 -> 8 -> 총 12
level=3: 첫 번째 퍼즐: 1<=3 -> 4, 두 번째: 3<=3 -> 2 -> 총 6
따라서 level=3이 최소.
만약 첫 번째 퍼즐의 난이도가 3이라면?
level은 최소 3이어야 합니다.
level=3: 첫 번째 퍼즐: 3<=3 -> 4, 두 번째: 3<=3 -> 2 -> 총 6 -> 성공 -> 답 3
첫 번째 퍼즐의 난이도가 2라면?
level은 최소 2.
level=2: 첫 번째: 2<=2 -> 4, 두 번째: 3>2 -> 8 -> 총 12 -> limit=10이면 실패
level=3: 성공 -> 답 3
따라서 첫 번째 퍼즐의 난이도가 2인 경우, level=2로는 12가 되어 실패하고 level=3이 필요.
이제, 우리의 이진 탐색은 첫 번째 퍼즐의 난이도가 2인 경우:
low = 2, high = max(diffs)=3
mid = (2+3)//2 = 2 -> t = calc_time(2) = 4 + (3>2 -> 8) = 12 > limit(10) -> low = 3
mid=3 -> t=6 <=10 -> ans=3, high=2 -> 종료.
따라서 3 반환.
또 다른 예시:
diffs = [1, 2, 3, 4], times = [1,1,1,1], limit=10
첫 번째 퍼즐: 1 -> 시간 1
두 번째: level이 2이상이면?
diff[1]=2: level>=2 -> 1
level<2 (level=1) -> (2-1)*(1+1)+1 = 2+1=3
세 번째: diff[2]=3
level>=3 -> 1
level=2 -> (3-2)*(1+1)+1 = 2+1=3
level=1 -> (3-1)*(1+1)+1 = 4+1=5
네 번째: diff[3]=4
level>=4 -> 1
level=3 -> (4-3)*(1+1)+1=2+1=3
level=2 -> (4-2)*(1+1)+1=4+1=5
level=1 -> (4-1)*(1+1)+1=6+1=7
총 시간:
level=4: 1+1+1+1=4
level=3: 첫 퍼즐: level=3>=1 -> 1,
두 번째: 2<=3 -> 1,
세 번째: 3<=3 -> 1,
네 번째: 4>3 -> (4-3)*(1+1)+1=3 -> 총 1+1+1+3=6
level=2:
첫 퍼즐: 1<=2 -> 1
두 번째: 2<=2 -> 1
세 번째: 3>2 -> (3-2)*2+1=3
네 번째: 4>2 -> (4-2)*2+1=5 -> 총 1+1+3+5=10
level=1:
첫 퍼즐: 1<=1 -> 1
두 번째: 2>1 -> (2-1)*2+1=3
세 번째: 3>1 -> (3-1)*2+1=5
네 번째: 4>1 -> (4-1)*2+1=7 -> 총 1+3+5+7=16
따라서 limit=10일 때, level=2이면 10으로 통과 -> 최소 level=2
우리의 이진 탐색:
min_level = diffs[0]=1
max_level = max(diffs)=4
calc_time(1)=16>10 -> 실패
calc_time(2)=10<=10 -> 성공 -> ans=2, 그리고 더 작은 level이 있는지 확인:
low=1, high=4 -> mid=2 -> 성공 -> high=1 -> 이제 low=1, high=1 -> mid=1 -> 16>10 -> 실패 -> low=2 -> 종료.
따라서 2 반환.
그러나 level=2가 최소이므로 맞습니다.
하지만 level=0? -> 첫 번째 퍼즐의 난이도가 1이므로 level=0이면 첫 퍼즐을 풀 수 없습니다.
따라서 level은 1부터 시작해야 하지만, min_level을 첫 퍼즐의 난이도로 설정했으므로 1입니다.
주의: 첫 번째 퍼즐의 난이도가 1이므로, level=1이면 첫 퍼즐은 풀 수 있습니다.
따라서 이진 탐색의 범위는 [diffs[0], max(diffs)] 입니다.
그러나 만약 모든 퍼즐의 난이도가 0인 경우? -> 문제에서 양의 정수라고 했으므로, 최소 1입니다.
구현 시 주의:
n=1인 경우 (퍼즐이 하나)
첫 번째 퍼즐만 있음 -> 이전 퍼즐이 없으므로,
if diffs[0] <= level: 시간 = times[0]
else:
# 틀린 횟수 = diffs[0] - level
# 하지만 이전 퍼즐이 없으므로, time_prev=0으로 처리?
# 문제에서 첫 번째 퍼즐은 이전 퍼즐이 없으므로, 틀렸을 때 이전 퍼즐을 다시 풀지 않습니다.
# 따라서 첫 번째 퍼즐은 틀리면 안 된다고 해석?
# 우리의 가정: 첫 번째 퍼즐은 무조건 한 번에 풀린다. -> times[0] 만 사용.
따라서 n=1인 경우:
level >= diffs[0] 이어야 하고, 총 시간 = times[0]
따라서 calc_time 함수는 n=1인 경우를 자연스럽게 처리합니다.
코드 구현:
def calc_time(diffs, times, level):
total = times[0] # 첫 번째 퍼즐
n = len(diffs)
for i in range(1, n):
if diffs[i] <= level:
total += times[i]
else:
total += (diffs[i] - level) * (times[i] + times[i-1]) + times[i]
return total
이제 solution 함수에서:
if n==0:
return 0 # 퍼즐이 없으면 0
max_level = max(diffs)
# max_level일 때의 총 시간 계산
total_max = calc_time(diffs, times, max_level) # 이 때는 모든 퍼즐이 한 번에 풀리므로, sum(times)와 같을까?
# n>=2인 경우, 두 번째 퍼즐부터는 모두 diffs[i] <= max_level 이므로 times[i]를 더함 -> 따라서 sum(times)와 같다.
# n=1인 경우: times[0] -> sum(times)와 같다.
if total_max > limit:
return -1
low = diffs[0] # 첫 번째 퍼즐의 난이도
high = max_level
ans = max_level # 일단 max_level은 가능
while low <= high:
mid = (low+high)//2
t = calc_time(diffs, times, mid)
if t <= limit:
ans = mid
high = mid - 1
else:
low = mid + 1
return ans
테스트: n=1, diffs=[5], times=[10], limit=10
min_level = 5
max_level = 5
total_max = 10 <= limit -> 이진 탐색: low=5, high=5 -> mid=5 -> t=10<=10 -> ans=5 -> return 5
만약 limit=9라면?
total_max=10>9 -> return -1
또 다른 테스트: n=1, diffs=[5], times=[10], limit=10 -> 5
n=1, diffs=[5], times=[10], limit=15 -> 5
n=1, diffs=[3], times=[10], limit=10 -> 3
n=2: diffs=[1,5], times=[1,10], limit=?
level의 범위: [1,5]
level=5: 총 시간 = 1 + 10 = 11
level=4: 두 번째 퍼즐: 5>4 -> (5-4)*(10+1)+10 = 1*11+10 = 21 -> 총 1+21=22
level=3: 5>3 -> (5-3)*11+10 = 22+10=32 -> 총 33
level=2: (5-2)*11+10 = 33+10=43 -> 44
level=1: (5-1)*11+10 = 44+10=54 -> 55
따라서 level=5일 때 11, level=4일 때 22, ...
limit=11: level=5 -> 11<=11 -> 성공 -> 최소 level=5
limit=10: level=5 -> 11>10 -> 실패 -> -1 반환?
하지만 level=5일 때 11>10 이므로, level 5로도 10초 내에 풀 수 없고,
level을 5보다 높여도 총 시간은 11로 동일 -> 따라서 -1
그러나 level=5일 때 두 번째 퍼즐: 5<=5 -> 10초만 소요 -> 총 1+10=11?
맞습니다.
따라서 limit=10이면 11>10 -> 실패.
하지만 level=5일 때 두 번째 퍼즐을 푸는 시간이 10초인데, 첫 번째 퍼즐 1초를 합하면 11초입니다.
따라서 -1 반환.
그러나 문제에서 제한 시간 내에 풀 수 없는 경우에 대한 반환을 어떻게 할지 명시되지 않았으므로,
문제가 요구하는 대로 -1을 반환합니다.
이제 코드를 작성합니다.
주의: 이진 탐색에서 항상 해를 찾을 수 있도록,
max_level일 때 total_max <= limit 이면 해가 존재하고, 아니면 -1을 반환합니다.
따라서:
total_max = calc_time(diffs, times, max_level)
if total_max > limit:
return -1
... 이진 탐색 ...
이진 탐색은 항상 [diffs[0], max_level] 사이의 해를 찾습니다.
하지만 이진 탐색에서 low가 diffs[0]이고, 이 범위 내에서 조건을 만족하는 가장 작은 level을 찾습니다.
이 코드를 제출합니다.
그러나 문제에서 첫 번째 퍼즐에 대한 처리에 대한 명확한 해석이 없어서 우리의 가정에 따랐습니다.
만약 문제의 의도가 첫 번째 퍼즐도 틀렸을 때 이전 퍼즐이 없으므로, 첫 번째 퍼즐을 틀리면 이전 퍼즐을 다시 풀 수 없어서 게임이 진행되지 않는다고 본다면,
첫 번째 퍼즐은 무조건 맞춰야 하므로 level>=diffs[0]이어야 한다는 가정은 맞습니다.
따라서 이대로 구현합니다.
하지만, 첫 번째 퍼즐을 틀릴 수는 없지만, 두 번째 퍼즐을 풀 때 첫 번째 퍼즐을 다시 풀 수 있으므로,
첫 번째 퍼즐은 틀리지 않아도 됩니다. (이미 맞춘 첫 번째 퍼즐을 다시 풀기만 하면 됨)
그러나 첫 번째 퍼즐을 풀 때는 틀리면 안 됩니다.
첫 번째 퍼즐을 풀 때 틀리면, 이전 퍼즐이 없기 때문에 다시 풀 수 없으므로 게임이 진행되지 않습니다.
따라서 첫 번째 퍼즐은 반드시 한 번에 맞춰야 합니다.
이 가정은 변함없습니다.
코드 작성:</think>### 문제 해결 방법
주어진 퍼즐 게임에서 제한 시간 내에 모든 퍼즐을 해결하기 위한 최소 숙련도(level)를 찾는 문제입니다. 핵심은 다음과 같습니다:
1. **첫 번째 퍼즐**: 이전 퍼즐이 없으므로 반드시 `diff[0] ≤ level`이어야 합니다. 소요 시간은 `times[0]`입니다.
2. **이후 퍼즐**(i ≥ 1):
- `diff[i] ≤ level`: 한 번에 풀리며, 소요 시간은 `times[i]`입니다.
- `diff[i] > level`: `(diff[i] - level)`번 틀리고, 각 틀릴 때마다 `(times[i] + times[i-1])` 시간이 소요되며, 마지막에 `times[i]` 시간이 추가됩니다. 총 시간은 `(diff[i] - level) × (times[i] + times[i-1]) + times[i]`입니다.
### 해결 전략
1. **이진 탐색**으로 최소 level 탐색:
- **하한(low)**: 첫 번째 퍼즐의 난이도 `diffs[0]` (이보다 작으면 첫 퍼즐 풀 수 없음).
- **상한(high)**: 모든 퍼즐의 최대 난이도 `max(diffs)` (이 값이면 모든 퍼즐 한 번에 풀림).
2. **시간 계산 함수**: 주어진 level로 모든 퍼즐을 풀 때의 총 시간을 계산합니다.
3. **예외 처리**: `max(diffs)` level에서도 제한 시간을 초과하면 풀 수 없으므로 `-1` 반환.
### 코드 구현
```python
def solution(diffs, times, limit):
n = len(diffs)
if n == 0:
return 0 # 퍼즐이 없는 경우
max_level = max(diffs)
# max_level일 때 총 시간 계산 (모든 퍼즐 한 번에 풀림)
total_max = times[0]
for i in range(1, n):
total_max += times[i]
# max_level로도 제한 시간 초과 시 -1 반환
if total_max > limit:
return -1
# 이진 탐색
low = diffs[0]
high = max_level
ans = max_level
while low <= high:
mid = (low + high) // 2
total_time = times[0] # 첫 번째 퍼즐 시간
for i in range(1, n):
if diffs[i] <= mid:
total_time += times[i]
else:
# 틀린 횟수 = (diff[i] - mid)
total_time += (diffs[i] - mid) * (times[i] + times[i-1]) + times[i]
if total_time <= limit:
ans = mid
high = mid - 1 # 더 작은 level 탐색
else:
low = mid + 1
return ans
```
### 예제 설명
**입력**: `diffs = [1, 5]`, `times = [1, 10]`, `limit = 11`
- **level = 5**:
- 첫 퍼즐: `1 ≤ 5` → 시간 1
- 두 번째 퍼즐: `5 ≤ 5` → 시간 10
총 시간 = 1 + 10 = 11 (limit 만족 → 최소 level 5)
- **level = 4**:
- 두 번째 퍼즐: `5 > 4` → `(5-4)×(10+1) + 10 = 21`
총 시간 = 1 + 21 = 22 (limit 초과)
**출력**: `5`