-
[프로그래머스] 퍼즐게임첼린지 자바 이진탐색코딩테스트 2025. 4. 12. 16:04반응형
https://school.programmers.co.kr/learn/courses/30/lessons/340212
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
/** * * @param diffs 난이도 모음 * @param times time_cur 모음 * @param limit 총 제한 시간. * @return limit안에 모든 퍼즐을 풀 수 있는 최소 level */
접근
diffs에서 최고 레벨을 구한 후 / 2씩 범위를 줄여가며 찾으면 좋겠다고 생각했다.
그러나 어떤 방식으로 diff / 2 한 후 +-로 조정해야 할지 갈피를 잡지 못했음.public int solution(int[] diffs, int[] times, long limit) { int minLevel = 1; int maxLevel = 0; //모든 스테이지를 다 클리어 했을 때 총 소요시간이 limit와 근사한 값이 나오면 최소 레벨. //최고 스테이지 먼저 찾아봄 for(int i = 0; i < diffs.length; i ++){ maxLevel = Math.max(maxLevel, diffs[i]); } int test = maxLevel / 2; getMidClearLevel(diffs, times, limit, test); return minLevel; } public int getMidClearLevel(int[] diffs, int[] times, long limit, int level){ long time_prev = 0; for(int i = 0; i < diffs.length; i ++){ int diff = diffs[i]; int time_cur = times[i]; if(diff > level){ time_prev += time_cur; } else { time_prev += (diff - level) * (time_prev + time_cur); } } if(time_prev > limit) getMidClearLevel(diffs, times, limit, level + 1); return level; }
2차시도
GPT의 도움으로 코드를 수정했다. 반복 처리를 하며 범위를 좁혀가는 방식이었다.
하지만 제출 후 14번 케이스의 계속적인 실패 발생public int solution2(int[] diffs, int[] times, long limit) { int left = 0; // 최소 난이도 int right = 100000; // 최대 레벨 범위 (제한이 없으면 적당히 크게 잡기) int answer = -1; while (left <= right) { int mid = (left + right) / 2; if (canClearAll(diffs, times, mid, limit)) { answer = mid; right = mid - 1; // 더 낮은 레벨로 시도 } else { left = mid + 1; // 더 높은 레벨로 올려야 함 } } answer = answer == 0 ? 1 : answer; return answer; } private boolean canClearAll(int[] diffs, int[] times, int level, long limit) { long totalTime = 0; for (int i = 0; i < diffs.length; i++) { if (diffs[i] <= level) { totalTime += times[i]; } else { int time_prev = i == 0 ? 0 : times[i - 1]; long penalty = Math.max(0L, (long) diffs[i] - level); totalTime += (penalty * (time_prev + times[i]) + times[i]); } // 시간 초과 방지 if (totalTime > limit) { return false; } } return true; }
다른 사람의 답변 참고
https://jincchan.tistory.com/57
동일하게 14번케이스에서 문제가 발생한 사람들이 있었다.
그 중 제일 맘에든 케이스를 참고하였다.public int solution3(int[] diffs, int[] times, long limit) { int maxValue = Arrays.stream(diffs).max().isPresent()? Arrays.stream(diffs).max().getAsInt() : 0; int minValue = 1; while (minValue < maxValue) { int level = (maxValue + minValue) / 2; long time = calTime(diffs, times, level); if(limit >= time) { maxValue = level; } else { minValue = level+1; } } return maxValue; } private long calTime(int[] diffs, int[] times, int level){ long time = 0; for(int i = 0; i < diffs.length; i++){ if(diffs[i] <= level){ time += times[i]; } else { int prev_time = i == 0 ? 0 : times[i -1]; time += (long) (prev_time + times[i]) * (diffs[i] - level) + times[i]; } } return time; }
차이 요약
solution2 solution3 이진 탐색 범위 [0, 100000] 등 제한된 범위로 고정 min = 1, max = max(diffs)로 유동적 종료 조건 left <= right + answer == 0이면 1로 강제 설정 min < max, 반환값 maxValue 자체로 결정 패널티 적용 Math.max(0, diff - level)로 예외 처리 무조건 (diff - level) 사용 (단, level은 절대 작지 않음) 반환 결과 보정 answer == 0 → 1 처리 없음 반응형'코딩테스트' 카테고리의 다른 글
[프로그래머스 level2] 도넛과 막대 그래프 자바 DFS (Map, Set) (0) 2025.04.15 [프로그래머스 level2] 충돌위험 찾기 자바 Map활용 (0) 2025.04.14 [프로그래머스] 암호해독 자바 조합 (2) 2025.04.11 [프로그래머스] 지게차와 크레인 자바 BFS (0) 2025.04.10 [프로그래머스] 서버증설횟수 자바 (0) 2025.04.10