메모리: 105 MB, 시간: 75.97 ms
코딩테스트 연습 > 월간 코드 챌린지 시즌3
정확성: 100.0
합계: 100.0 / 100.0
2025년 03월 24일 04:20:44
어느 왕국에 하나 이상의 도시들이 있습니다. 왕국의 왕은 새 도시를 짓기로 결정하였습니다. 해당 도시를 짓기 위해서는 도시를 짓는 장소에 금 a kg과 은 b kg이 전달되어야 합니다.
각 도시에는 번호가 매겨져 있는데, i번 도시에는 금 g[i] kg, 은 s[i] kg, 그리고 트럭 한 대가 있습니다. i번 도시의 트럭은 오직 새 도시를 짓는 건설 장소와 i번 도시만을 왕복할 수 있으며, 편도로 이동하는 데 t[i] 시간이 걸리고, 최대 w[i] kg 광물을 운반할 수 있습니다. (광물은 금과 은입니다. 즉, 금과 은을 동시에 운반할 수 있습니다.) 모든 트럭은 같은 도로를 여러 번 왕복할 수 있으며 연료는 무한대라고 가정합니다.
정수 a, b와 정수 배열 g, s, w, t가 매개변수로 주어집니다. 주어진 정보를 바탕으로 각 도시의 트럭을 최적으로 운행했을 때, 새로운 도시를 건설하기 위해 금 a kg과 은 b kg을 전달할 수 있는 가장 빠른 시간을 구해 return 하도록 solution 함수를 완성해주세요.
a, b ≤ 109g의 길이 = s의 길이 = w의 길이 = t의 길이 = 도시 개수 ≤ 105
g[i], s[i] ≤ 109w[i] ≤ 102t[i] ≤ 105a ≤ g의 모든 수의 합b ≤ s의 모든 수의 합| a | b | g | s | w | t | result |
|---|---|---|---|---|---|---|
| 10 | 10 | [100] | [100] | [7] | [10] | 50 |
| 90 | 500 | [70,70,0] | [0,0,500] | [100,100,2] | [4,8,1] | 499 |
입출력 예 #1
입출력 예 #2

코드
class Solution {
public long solution(int a, int b, int[] g, int[] s, int[] w, int[] t) {
long ans=0;
long left = 0;
long right = (long) 1e15;
long res = 0;
while(left <= right){
long mid = left + (right-left) / 2L;
if(canBuild(a, b, g, s, w, t, mid)){
res = mid;
right = mid-1;
}
else left = mid+1;
}
return res;
}
private static boolean canBuild(int a, int b, int[] g, int[] s, int[] w, int[] t, long mid){
long goldW = 0; // a이상이어야함
long silverW = 0; // b이상이어야함
long totalW = 0; // a+b이상이어야함
for(int i=0; i<w.length; i++){
long cnt = (long) mid / (2L * (long) t[i]);
if(mid % (2L * (long) t[i]) >= t[i]) cnt++; // 편도 1회
long maxW = cnt * w[i]; // 최대한 트럭에 싣고 옮길때 양
long maxGold = Math.min(maxW, g[i]); // 보유 금 넘지 않게
long maxSilver = Math.min(maxW, s[i]); // 보유 은 넘지 않게
long moveW = Math.min(g[i] + s[i], maxW);
totalW += moveW;
goldW += maxGold;
silverW += maxSilver;
}
return totalW >= a+b && goldW >= a && silverW >= b;
}
}