Algorithm/Java

[프로그래머스/JAVA] 콜라 문제

dbfl9911 2024. 10. 30. 15:32
반응형

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

📌 문제 요약 

빈 병 a개를 가져가면 콜라 b병을 주는 마트가 있다.
현재 n개의 빈 병이 있을 때, 상빈이가 받을 수 있는 콜라의 총 병 수를 계산하라.

  • 빈 병이 a개 이상이어야 교환 가능.
  • 교환 후 남은 병은 다음 교환에 사용 가능.

 



[ 오답 노트 ]

 

❌ 기존 오답 코드

class Solution {
    public int solution(int a, int b, int n) {
        // 빈 병 2개 -> 1개 줌  (==> 2)
        // (만약 빈 병 2개 -> 2개 준다면?) (==> 1)
        // -------------------
        // 빈 병 20개 -> 10개 줌
        // 빈 병 10개 -> 5개 줌
        // 빈 병 5개 -> 2개 줌 .. 빈병 1개 남음
        // 빈 병 2개 -> 1개 줌
        // 빈 병 5개일 때 남은 1병 + 위에 1개 -> 1개 줌
        // 총 10 + 5 + 2 + 1 + 1 = 19개 (정답)
        int answer = 0;
        int subsum = 0; // 나머지 병들? 
        while(n > 0) {
            if(n % (a / b) != 0) {  // 1 % (2) == 1
                if(n == 1) { 
                    if(subsum > 0) {
                        n += subsum; // n = 2
                        subsum = 0;
                    }else {
                        break;
                    }
                }
                subsum += n % (a / b); // subsum = 5 % (2) = 1
            }
            
            // a병을 가져다주면 b병을 줌
            n = n / (a / b); // n = 2 / (2) = 1
            answer += n; // 10 + 5 + 2 + 1 + 1
        }
        
        return answer;
    }
}


📌 기존 코드의 문제점

 

1. 교환 계산이 잘못됨

  • (a / b)는 교환 비율이 아니라 단순 나누기 결과일 뿐, 문제의 조건을 제대로 반영하지 못함.
  • 올바른 계산은 (n / a) * b 형태로 처리해야 함.

 

2. subsum 변수의 불필요한 복잡성

  • 남는 병 처리를 복잡하게 구현해 코드 가독성이 떨어짐.
  • 남은 병은 단순히 n % a로 관리할 수 있음.

 

3. 종료 조건 미흡

n이 1일 때 종료 조건이 불분명하고, subsum 값에 의존해 비효율적인 로직이 추가됨.

 

 

 



[ 정답 코드 & 올바른 풀이 ]


📌 올바른 풀이

 

1. 교환 조건

빈 병이 a개 이상이어야 콜라를 받을 수 있다.
반복문을 while (n >= a)로 설정.

 

2. 교환 병 계산

n / a는 교환 가능한 횟수를 의미하며, 여기에 b를 곱해 실제로 받을 병 수를 구한다

 

3. 남은 병 처리

교환 후 남은 병은 n % a로 계산하고, 새로 받은 병과 합산해 다음 반복에 사용

 



📌 정답 코드

class Solution {
     public int solution(int a, int b, int n) {
        int answer = 0;
        
        // 보유 중인 빈 병이 a개 미만이면, 추가적으로 빈 병을 받을 수 x
        while(n >= a) {
             // (만약 빈 병 2개 -> 2개 준다면?)
             // (빈 병 20개 -> 20개 줌)
            // 원래 교환 수에 한번 교환당 받는 병수를 곱해준다
            int exchange = (n / a) * b; // 10
            answer += exchange; // 10 + ...
            // 어차피 나머지가 0일때는 더할때 영향을 미치지 않으므로 if 조건 안나눠도 됌
            n = (n % a) + exchange;
        }

        return answer;
    }
}
반응형