<Lv.3> 금과 은 운반하기 (프로그래머스 : C#)

이도희·2023년 9월 16일
0

알고리즘 문제 풀이

목록 보기
166/185

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
(모든 트럭은 같은 도로를 여러 번 왕복할 수 있다.)

새로운 도시 건설을 위해 금과 은을 전달할 수 있는 가장 빠른 시간 반환하기

  • Input
    전달되어야 하는 금, 은 양 (a,b), 각 도시의 금과 은의 양 (g, s), 이동 시간 t, 운반 가능한 최대 광물 무게 w
  • Output
    새로운 도시 건설을 위해 금과 은을 전달할 수 있는 가장 빠른 시간 반환

예제

시도 1.

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;
    }
}

결과

profile
하나씩 심어 나가는 개발 농장🥕 (블로그 이전중)

0개의 댓글