Algorithm

[프로그래머스/JavaScript] Lv.2 택배 배달과 수거하기

cob 2023. 9. 1. 17:33

 

https://school.programmers.co.kr/learn/courses/30/lessons/150369

 

프로그래머스

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

programmers.co.kr

 

 


1. 문제 설명

당신은 일렬로 나열된 n개의 집에 택배를 배달하려 합니다. 배달할 물건은 모두 크기가 같은 재활용 택배 상자에 담아 배달하며, 배달을 다니면서 빈 재활용 택배 상자들을 수거하려 합니다.
배달할 택배들은 모두 재활용 택배 상자에 담겨서 물류창고에 보관되어 있고, i번째 집은 물류창고에서 거리 i만큼 떨어져 있습니다. 또한 i번째 집은 j번째 집과 거리 j - i만큼 떨어져 있습니다. (1 ≤ i ≤ j ≤ n)
트럭에는 재활용 택배 상자를 최대 cap개 실을 수 있습니다. 트럭은 배달할 재활용 택배 상자들을 실어 물류창고에서 출발해 각 집에 배달하면서, 빈 재활용 택배 상자들을 수거해 물류창고에 내립니다. 각 집마다 배달할 재활용 택배 상자의 개수와 수거할 빈 재활용 택배 상자의 개수를 알고 있을 때, 트럭 하나로 모든 배달과 수거를 마치고 물류창고까지 돌아올 수 있는 최소 이동 거리를 구하려 합니다. 각 집에 배달 및 수거할 때, 원하는 개수만큼 택배를 배달 및 수거할 수 있습니다.

제한사항

 

 


2. 입출력

입출력

 

 

 


3. 문제 풀이

최단거리를 구하기 왕복으로 이동하기 때문에 이동거리가 먼 마지막부터 확인해 택배를 감소시켜야 한다. 마찬가지 이유로 회수 또한, 마지막부터 확인해 감소시킨다.
function solution(cap, n, deliveries, pickups) {
  let answer = 0;
  
  // 1) 택배 배달/회수 작업이 없을 때까지 반복한다.
  while(deliveries.length || pickups.length) {
    let dbox = cap, pbox = cap;     // dbox : 배달 개수, pbox : 회수 개수
    let dTrue = true, pTrue = true; // dTrue : 배달 이동 위치 확인 여부, pTrue : 회수 이동위치 확인 여부
    let dNum = 0, pNum = 0;         // dNum : 배달 위치, pNum : 회수 위치
    /* 마지막 배달이 끝나면 첫 번째 회수를 시작한다. */
    
    // 2) 배달 가능한 택배가 있으면서, 배달할 집도 있을 경우만 
    while(dbox >= 0 && deliveries.length) {
      let box = deliveries.pop();    // 배달 받을 택배 개수
      
      // 3) 배달 받을 택배도 있을 경우만
      if(dTrue && box) { 
        dNum = deliveries.length + 1; // 배달 위치 저장
        dTrue = false;
      }
      
      // 4) (배달 가능한 택배) - (배달 받을 택배) >= 0 경우
      if(dbox- box >= 0) dbox -= box;  
      else deliveries.push((dbox-=box)*-1); // 배달 받을 택배가 남아 있으므로 다시 push
    }
    
    // 5) 회수 가능한 택배가 있으면서, 회수할 집도 있을 경우만
    while(pbox >= 0 && pickups.length) {
      let box = pickups.pop();    // 회수할 택배 개수
      
      // 6) 회수할 택배도 있을 경우만
      if(pTrue && box) { 
        pNum = pickups.length + 1; // 회수 위치 저장
        pTrue = false;
      }
      
      // 7) (회수 가능한 택배) - (회수할 택배) >= 0 경우
      if(pbox- box >= 0) pbox -= box;
      else pickups.push((pbox-=box)*-1); // 회수할 택배가 남아 있으므로 다시 push
    }
    
    // 8) 택배를 배달하든 회수하든 어차피 해당 위치만큼 움직여 왕복해야 하기 때문에 큰값 * 2를 한다.
    answer += (2 * Math.max(dNum, pNum));
  }
  
  return answer;
}

 

 

 


4. 추가 테스트 케이스

cap(int) n(int) deliveries(int[]) pickups(int[]) RETURN(기대 값)
2 2 [0, 0] [0, 0] 0
반응형