문제
https://school.programmers.co.kr/learn/courses/30/lessons/132267
다음과 같은 콜라 문제가 있다.
콜라 빈 병 2개를 가져다주면 콜라 1병을 주는 마트가 있다. 빈 병 20개를 가져다주면 몇 병을 받을 수 있는가?
단, 보유 중인 빈 병이 2개 미만이면, 콜라를 받을 수 없다.
상빈이는 그림과 같은 방법으로 콜라 문제를 풀어냈다.
빈 콜라병 20병을 가져가서 10병을 받는다. 받은 10병을 비우고 5병을 받는다. 5병 중 4병을 비우고 2병을 받고, 또 2병을 비우고 1병을 받는다. 받은 1병과 5병을 받았을 때 남은 1병을 비워서 1병을 또 받는다. 따라서 총 10 + 5 + 2 + 1 + 1 = 19병의 콜라를 받는다.
만약 빈 병 a개를 가져다주면 콜라 b병을 주는 마트가 있을 때, 빈 병 n개를 가져다주면 몇 병을 받을 수 있을까?
내 풀이
1. n개 병을 가져갔을 떄 받는 병의 수를 계산한다.
re = (n // a) * b
2. 받은 병의 수와 가져가지 않고 남은 병의 수를 n개라고 취급한다.
n = re + n % a
3. 병의 수가 a개 미만인 경우에는 교환이 불가능하므로, n이 a 이상인 경우에만 위 과정을 반복한다.
반복하면서 받은 병의 수를 누적하여 합한다.
def solution(a, b, n):
answer = 0
while n >= a:
re = (n // a) * b
n = re + n % a
answer += re
return answer
다른 사람 풀이
이런 문제는 수학 머리가 있으면 반복문을 제거할 수 있는데, 그런 풀이가 딱 있었다. 즉, 나는 수학 머리가 없었다……😂.
1. a개를 주고 b개를 받는 과정은 a - b개를 소비하는 것이다.
2. 병의 수가 b개 미만인 경우에는 교환이 불가능하므로 처음 병의 개수는 n - b개라고 할 수 있다.
3. n - b개의 병을 a - b개씩 교환할 때마다 b개를 받으므로 (n - b) / (a - b)의 몫에 b를 곱한 결과가 받는 병의 개수가 된다.
def solution(a, b, n):
answer = (n - b) // (a - b) * b
return answer
참고 문서
https://school.programmers.co.kr/learn/courses/30/lessons/132267