https://school.programmers.co.kr/learn/courses/30/lessons/340212
당신은 순서대로 n개의 퍼즐을 제한 시간 내에 풀어야 하는 퍼즐 게임을 하고 있습니다. 각 퍼즐은 난이도와 소요 시간이 정해져 있습니다. 당신의 숙련도에 따라 퍼즐을 풀 때 틀리는 횟수가 바뀌게 됩니다. 현재 퍼즐의 난이도를 diff, 현재 퍼즐의 소요 시간을 time_cur, 이전 퍼즐의 소요 시간을 time_prev, 당신의 숙련도를 level이라 하면, 게임은 다음과 같이 진행됩니다.
예를 들어 diff = 3, time_cur = 2, time_prev = 4인 경우, level에 따라 퍼즐을 푸는데 걸리는 시간은 다음과 같습니다.
퍼즐 게임에는 전체 제한 시간 limit가 정해져 있습니다. 제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값을 구하려고 합니다. 난이도, 소요 시간은 모두 양의 정수며, 숙련도도 양의 정수여야 합니다.
퍼즐의 난이도를 순서대로 담은 1차원 정수 배열 diffs, 퍼즐의 소요 시간을 순서대로 담은 1차원 정수 배열 times, 전체 제한 시간 limit이 매개변수로 주어집니다. 제한 시간 내에 퍼즐을 모두 해결하기 위한 숙련도의 최솟값을 정수로 return 하도록 solution 함수를 완성해 주세요.
제한사항🚫
입출력 예
입출력 예 설명
입출력 예 #1
총 2 + 16 + 7 = 25의 시간을 사용하여 모든 퍼즐을 해결할 수 있습니다. 숙련도가 3보다 작은 경우 제한 시간인 30 이내에 모든 퍼즐을 해결할 수 없습니다.
따라서 3을 return 해야 합니다.
입출력 예 #2
총 6 + 21 + 30 + 2 = 59의 시간을 사용하여 모든 퍼즐을 해결할 수 있습니다. 숙련도가 2보다 작은 경우 제한 시간인 59 이내에 모든 퍼즐을 해결할 수 없습니다.
따라서 2를 return 해야 합니다.
입출력 예 #3
총 2 + 313 + 1385 + 4 + 3 = 1707의 시간을 사용하여 모든 퍼즐을 해결할 수 있습니다. 숙련도가 294보다 작은 경우 제한 시간인 1723 이내에 모든 퍼즐을 해결할 수 없습니다.
따라서 294를 return 해야 합니다.
입출력 예 #4
총 9999 + 1152264001 + 1152283999 + 1152188001 = 3456746000의 시간을 사용하여 모든 퍼즐을 해결할 수 있습니다. 숙련도가 39354보다 작은 경우 제한 시간인 3456789012 이내에 모든 퍼즐을 해결할 수 없습니다.
따라서 39354를 return 해야 합니다.
class Solution {
//현재 level 값으로 가능한지 판단하는 함수
static boolean isImpossible(int[] diffs, int[] times, long level, long limit){
long t = (long)times[0];
for(int i =1; i<times.length; i++){
if(diffs[i] > level){
t += ((long)diffs[i] - level) * ((long)times[i-1] + (long)times[i]);
}
t += (long)times[i];
}
return limit < t;
}
/*
이진탐색을 활용, mid값을 level로 설정
*/
public int solution(int[] diffs, int[] times, long limit) {
//diff: 난이도, time_cur: 소요시간, time_prev: 이전 소요시간, level: 숙련도
//diff<=level time_cur만큼 사용
//diff>level diff-level번 틀림 틀릴때 마다 time_cur 사용, 추가로 time_prev 시간을 사용해 이전 퍼즐 풀고 와야함 이 때는 난이도 상관없이 틀리지 않음, diff - level번 틀린 후에 다시 풀면 time_cur 시간 사용하여 해결
long left = 1;
long right = limit;
while(left < right){
long mid = (left + right) / 2;
if(isImpossible(diffs, times, mid, limit)){
left = mid + 1;
}else{
right = mid;
}
}
return (int)left;
}
}