프로그래머스

[프로그래머스] 택배 배달과 수거하기

양갱이요 2023. 3. 5. 21:24

프로그래머스 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/150369

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

public class Main {
    static class Solution {
        public long solution(int cap, int n, int[] deliveries, int[] pickups) {
			// delivery_last: 배송할 것이 남아있는 가장 먼 인덱스
			// pickup_last: 픽업할 것이 남아있는 가장 먼 인덱스
            int delivery_last = n - 1, pickup_last = n - 1;
            // 리턴할 답
            long answer = 0;
            
            // 배송이나 픽업할 것이 남아있을 때까지 반복한다
            // delivery_last 위치에 배송할 개수가 0 개 이면, 
        	// 그곳까지 방문할 필요 없다. 따라서 --delivery_last
            while (delivery_last >= 0 || pickup_last >= 0) {
                while (delivery_last >= 0 && deliveries[delivery_last] == 0)
                    --delivery_last;
                    
           		// pickup_last 위치에 픽업할 개수가 0 개 이면,
       			// 그곳까지 방문할 필요 없다. 따라서 --pickup_last
                while (pickup_last >= 0 && pickups[pickup_last] == 0)
                    --pickup_last;
            	// 이번 싸이클에서는 delivery_last, pickup_last 값들 중 큰 값 위치까지 방문해야 한다.
       			// 방문할 거리는 인덱스 + 1 이고, 그 거리까지 왕복해야 하므로 * 2 한다.
                answer += 2 * (1 + Math.max(delivery_last, pickup_last));
                // cap 용량까지 배송할 수 있다.
                int delivery_cap = cap;
                
                // 배송할 것이 남아있고, 배송 용량에 여유가 있을 때까지 반복한다
                while (delivery_last >= 0 && delivery_cap > 0) {
               		// 현재 delivery_last 위치에 배송 가능한 수(temp)는
          			// 남아있는 배송 용량과, 이 위치에 배송할 수 중 최소값이다.
                    int temp = Math.min(delivery_cap, deliveries[delivery_last]);
                    
                    // delivery_last 위치에 배송 가능한 수(temp) 만큼 배송한다.
                    delivery_cap -= temp;
                    deliveries[delivery_last] -= temp;
                    
                    // delivery_last 위치에 배송해야할 수 남은 값이 0 이면, --delivery_last
                    if (deliveries[delivery_last] == 0) --delivery_last;
                }
                // cap 용량까지 픽업할 수 있다.
                int pickup_cap = cap;
                
            	// 픽업할 것이 남아있고, 픽업 용량에 여유가 있을 때까지 반복한다
                while (pickup_last >= 0 && pickup_cap > 0) {
                
                    // 현재 pickup_last 위치에 픽업 가능한 수(temp)는
           			// 남아있는 픽업 용량과, 이 위치에 픽업할 수 중 최소값이다.
                    int temp = Math.min(pickup_cap, pickups[pickup_last]);
                    
                    // pickup_last 위치에 픽업 가능한 수(temp) 만큼 픽업한다.
                    pickup_cap -= temp;
                    pickups[pickup_last] -= temp;
                    
                    // pickup_last 위치에 픽업해야할 수 남은 값이 0 이면, --pickup_last
                    if (pickups[pickup_last] == 0) --pickup_last;
                }
            }
            return answer;
        }
    }

    public static void main(String[] args) {
        var sol = new Solution();

        int[] deliveries = new int[] { 1, 0, 3, 1, 2 };
        int[] pickups = new int[] { 0, 3, 0, 4, 0 };
        System.out.println(sol.solution(4, 5, deliveries, pickups));

        deliveries = new int[] { 1, 0, 2, 0, 1, 0, 2 };
        pickups = new int[] { 0, 2, 0, 1, 0, 2, 0 };
        System.out.println(sol.solution(2, 7, deliveries, pickups));
    }