https://school.programmers.co.kr/learn/courses/30/lessons/86053
어느 도시를 짓기 위해 금과 은 a, bkg가 전달되어야 한다.
도시 i
1. 금 g[i]kg, 은 s[i]kg, 트럭 한 대 존재. (i번 도시의 트럭은 오직 새 도시를 짓는 건설 장소와 i번 도시만을 왕복할 수 있음)
2. 트럭의 편도 이동 시간 = t[i]
3. 광물 최대 운반 무게 = w[i]kg
(모든 트럭은 같은 도로를 여러 번 왕복할 수 있다.)
새로운 도시 건설을 위해 금과 은을 전달할 수 있는 가장 빠른 시간 반환하기
total을 따로 두고 접근하는게 아니라 조건문으로 조금 복잡하게 처리하는 식으로 진행
(if문으로 현재 gold자체의 양이랑 goldFromCity 빼야하는 조건 등을 비교하는 식으로..?)
using System;
public class Solution {
public long solution(int a, int b, int[] g, int[] s, int[] w, int[] t) {
long answer = (long)Math.Pow(10, 15);
long left = 0;
long right = (long)Math.Pow(10, 15);
while (left <= right)
{
long mid = (left + right) / 2; // 운반에 걸리는 시간
long gold = a;
long silver = b;
// mid 기준 운반 가능한 양 구하기
for (int i = 0; i < w.Length; i++)
{
if (gold <= 0 && silver <= 0) break;
long moveTime = (mid - t[i]) / (2 * t[i]) + 1;
long mineralAmount = w[i] * moveTime; // 운반 가능한 양
// max를 운반 가능한 양으로 설정
long goldFromCityI = g[i] < mineralAmount ? g[i] : mineralAmount;
if (gold > 0 && g[i] > 0) // 운반해야할 gold가 남아있으면
{
if (gold < goldFromCityI)
{
mineralAmount -= gold;
gold = 0;
}
else
{
mineralAmount -= goldFromCityI;
gold -= goldFromCityI;
}
}
if (silver > 0 && mineralAmount > 0 && s[i] > 0) // 운반해야할 silver가 남아 있으면
{
long silverFromCityI = s[i] < mineralAmount ? s[i] : mineralAmount;
mineralAmount -= silverFromCityI;
silver -= silverFromCityI;
}
}
// 운반하기 시간 충분한 경우
if (gold <= 0 && silver <= 0)
{
right = mid - 1;
answer = Math.Min(answer, mid);
}
else // 운반하기 시간 부족한 경우
{
left = mid + 1;
}
}
return answer;
}
}
위의 방식으로 일부 테케가 통과가 계속 되지 않아서 total로 운반 가능한지 판단할 수 있도록 두는 식으로 변경했다.
using System;
public class Solution {
public long solution(int a, int b, int[] g, int[] s, int[] w, int[] t) {
long answer = (long)Math.Pow(10, 15);
long left = 0;
long right = (long)Math.Pow(10, 15);
while (left <= right)
{
long mid = (left + right) / 2; // 운반에 걸리는 시간
long gold = a;
long silver = b;
long total = 0;
// mid 기준 운반 가능한 양 구하기
for (int i = 0; i < w.Length; i++)
{
if (gold <= 0 && silver <= 0 && total >= a+b) break;
long moveTime = (mid - t[i]) / (2 * t[i]) + 1;
long mineralAmount = w[i] * moveTime; // 운반 가능한 양
total += g[i] + s[i] < mineralAmount ? g[i] + s[i] : mineralAmount;
// max를 운반 가능한 양으로 설정
long goldFromCityI = g[i] < mineralAmount ? g[i] : mineralAmount;
long silverFromCityI = s[i] < mineralAmount ? s[i] : mineralAmount;
gold -= goldFromCityI;
silver -= silverFromCityI;
}
// 운반하기 시간 충분한 경우
if (gold <= 0 && silver <= 0 && total >= a+b)
{
right = mid - 1;
answer = Math.Min(answer, mid);
}
else // 운반하기 시간 부족한 경우
{
left = mid + 1;
}
}
return answer;
}
}