프로그래머스 입문 120884 치킨 쿠폰
문제
치킨 한 마리를 주문할 때마다 쿠폰 1장이 발급된다.
쿠폰 10장을 모으면 치킨 한 마리로 교환할 수 있다.
쿠폰으로 받은 치킨에도 쿠폰 1장이 발급된다.
치킨 주문 수가 주어질 때, 쿠폰으로 받을 수 있는 최대 치킨의 수를 구하시오.
| chicken | result |
|---|---|
| 100 | 11 |
| 1,081 | 120 |
풀이
쿠폰으로 치킨 교환 과정 반복하기
#define COUPONS_PER_CHICKEN 10
int solution(int chicken)
{
int coupons = chicken;
int free_chickens = 0;
while (coupons >= COUPONS_PER_CHICKEN)
{
int exchanged_chickens = coupons / COUPONS_PER_CHICKEN;
free_chickens += exchanged_chickens;
coupons = exchanged_chickens + coupons % COUPONS_PER_CHICKEN;
}
return free_chickens;
}
이 코드의 핵심은 현재 보유한 쿠폰으로 치킨을 몇 마리 받을 수 있는지 매 회차 계산하는 것이다.
쿠폰으로 받은 치킨도 다시 쿠폰을 만들기 때문에, 받은 치킨 수만큼 쿠폰이 새로 생긴다.
따라서 다음 회차의 쿠폰 수는 이번 회차에 먹은 치킨 수와 10장이 되지 못해 사용하지 못 하고 남은 쿠폰 수를 더해 구한다.
| 보유 쿠폰 | 사용 쿠폰 | 남은 쿠폰 | 이번 회차 먹은 치킨 | 누적 공짜 치킨 |
|---|---|---|---|---|
| 1081 | 1080 | 1 | 108 | 108 |
| 109 | 100 | 9 | 10 | 118 |
| 19 | 10 | 9 | 1 | 119 |
| 10 | 10 | 0 | 1 | 120 |
| 1 | 종료 | 120 |
교환 비율 공식으로 계산하기
#define COUPONS_PER_CHICKEN 10
int solution(int chicken)
{
return (chicken - 1) / (COUPONS_PER_CHICKEN - 1);
}
이 문제는 쿠폰으로 받은 치킨도 다시 쿠폰 1장으로 바뀌기 때문에 이런 풀이 방법도 가능하다.
쿠폰 10장을 치킨 1마리로 교환하면 그 치킨에서 쿠폰 1장이 다시 생긴다.
결과적으로 공짜 치킨 1마리를 받을 때마다 보유 쿠폰은 10장이 아니라 9장씩 줄어든다.
28장으로 교환 과정 확인하기
예를 들어 쿠폰이 28장 있다면 다음처럼 교환된다.
- 1회차:
28 - 10 + 1 = 19- 보유 28장에서 쿠폰 10장을 사용해 치킨 1마리를 받고, 남은 쿠폰 18장에 새 쿠폰 1장이 더해져 쿠폰이 19장이 된다.
- 2회차:
19 - 10 + 1 = 10- 보유 19장에서 쿠폰 10장을 사용해 치킨 1마리를 받고, 남은 쿠폰 9장에 새 쿠폰 1장이 더해져 쿠폰이 10장이 된다.
- 3회차:
10 - 10 + 1 = 1- 보유 10장에서 쿠폰 10장을 사용해 치킨 1마리를 받고, 새 쿠폰 1장만 남는다.
따라서 쿠폰 28장으로는 공짜 치킨 3마리를 받을 수 있고, 최종적으로 쿠폰 1장이 남는다.
27장으로 교환 과정 확인하기
반대로 처음 보유한 쿠폰이 27장이라면 다음처럼 진행되고, 세 번째 교환은 할 수 없다.
- 1회차:
27 - 10 + 1 = 18- 보유 27장에서 쿠폰 10장을 사용해 치킨 1마리를 받고, 남은 쿠폰 17장에 새 쿠폰 1장이 더해져 쿠폰이 18장이 된다.
- 2회차:
18 - 10 + 1 = 9- 보유 18장에서 쿠폰 10장을 사용해 치킨 1마리를 받고, 남은 쿠폰 8장에 새 쿠폰 1장이 더해져 쿠폰이 9장이 된다.
따라서 쿠폰 27장으로는 공짜 치킨 2마리를 받을 수 있고, 최종적으로 쿠폰 9장이 남는다.
필요한 쿠폰 수를 식으로 정리하기
공짜 치킨을 x마리 받으려면 쿠폰 교환을 x번 해야 한다.
교환할 때마다 쿠폰 10장을 쓰지만, 받은 치킨에서 쿠폰 1장이 다시 나오므로 실제로는 쿠폰이 9장씩 줄어드는 것과 같다.
그래서 x번 교환하면 쿠폰은 총 9 * x장 줄어든다.
다만 쿠폰이 9 * x장만 있으면 마지막 교환을 하기 직전에 쿠폰이 9장만 남는다.
마지막 교환도 하려면 그 순간 쿠폰이 10장이어야 하므로, 처음에는 9 * x장보다 1장이 더 필요하다.
따라서 공짜 치킨을 x마리 받으려면 최소 9 * x + 1장의 쿠폰이 있어야 한다.
다시 정리하면, x는 쿠폰으로 받을 공짜 치킨 수이고 chicken은 처음 주문한 치킨 수이자 처음 가진 쿠폰 수이다.
그러므로 받을 수 있는 공짜 치킨의 최대 수는 9 * x + 1 <= chicken을 만족하는 가장 큰 x이다.
이 식에서 등식의 성질을 이용해 양변에서 1을 빼면 9 * x <= chicken - 1이 된다.
다시 9로 나누면 x <= (chicken - 1) / 9가 된다.
따라서 받을 수 있는 최대 공짜 치킨 수는 (chicken - 1) / 9로 계산할 수 있다.