본문 바로가기
알고리즘/필기

치킨 쿠폰

by 유시은 2020. 11. 25.

문제: 처음에 교환 쿠폰 n장이 있고, k장을 사용하면 1장의 쿠폰을 줄 때, 최대 몇 마리의 치킨을 받을 수 있는가?

 

 

사용한 총 쿠폰 수를 t라고 하자.

 

처음 n장이 있으니 t의 초기값은 n이다.

 

 

새로 받을 수 있는 쿠폰은 n // k 장이다. t += n // k

* 가지고 있는 쿠폰으로 최대한 많이 교환

 

이때 남는 쿠폰은 n // k + n % k 장이다. n = n % k + n // k

* 교환하지 못한 n % k 장 + 이제 새로 받은 n // k 장

 

이것을 새로 받을 수 있는 쿠폰이 0장이 될 때까지 반복하면 된다.

 

t = n
while n//k > 0:
    t += n//k
    n = n//k + n%k

 

 

이제 t를 한번에 구하자.

 

k개의 쿠폰을 사용하면 1개의 쿠폰을 받으므로, k - 1개의 쿠폰으로 치킨을 하나 받을 수 있다.

 

하지만 n // (k - 1) 은 n이 k - 1로 나누어 떨어질 때 문제가 발생한다.

 

쿠폰이 k - 1 장 남았을 때, 치킨을 일단 주문하고 받는 쿠폰으로 k개를 채워 거래하는 비상식적인 경우이다.

 

 

이런 경우는 n // (k - 1) - (n % (k - 1) == 0) 와 같이 처리해 줄 수 있다.

 

이는 (n - k) // (k - 1) + 1 과 동치이다.

 

 

조금 더 일반화하여 치킨을 하나 주문하면 c개의 쿠폰을 준다고 할 때,

 

(n - k) // (k - c) + 1 역시 성립한다.

 

 

import sys
input = sys.stdin.readline

for _ in range(int(input())):
    P, M, F, C = map(int, input().split())
    paidChicken = (M // P)
    s = d = 0

    d = paidChicken + (paidChicken*C)//F
    s = paidChicken
    if paidChicken*C >= F:
        s += (paidChicken*C - F) // (F - C) + 1
    print(s - d)

 

boj.kr/13199

 

13199번: 치킨 먹고 싶다

서울대학교 301동에는 아는 사람만 아는 “눕치킨”이란 치킨집이 있다. 이 치킨집은 여느 치킨집처럼 치킨을 시킬 때 마다 쿠폰을 C 장 주고, 쿠폰을 F 장 모으면 치킨을 공짜로 시킬 수 있다.

www.acmicpc.net

 

'알고리즘 > 필기' 카테고리의 다른 글

라빈-카프와 부분문자열 쿼리  (0) 2022.07.22
연속한 수의 XOR sum  (0) 2020.12.25
유니온 파인드  (0) 2020.09.11
Z  (0) 2020.08.15

댓글