https://www.acmicpc.net/problem/2502
2502번: 떡 먹는 호랑이
첫줄에 첫 날에 준 떡의 개수 A를 출력하고 그 다음 둘째 줄에는 둘째 날에 준 떡의 개수 B를 출력한다. 이 문제에서 주어진 D, K에 대해서는 항상 정수 A, B (1≤ A ≤ B)가 존재한다.
www.acmicpc.net
문제 접근
d[n] = d[n-1] + d[n-2]
n, d[n]이 주어질 때, 구해야 하는 값은 d[0]와 d[1]
첫번째 날 A개, 두번째 날 B개라면,
3번째 날: A + B
4번째 날: B + (A + B) = A + 2B
5번째 날: (A + B) + (A + 2B) = 2A + 3B
6번째 날: (A + 2B) + (2A + 3B) = 3A + 5B
계수의 변화를 살펴보면 A의 경우 1, 1, 2, 3...
B의 경우 1, 2, 3, 5...식으로 변하고 있다.
이를 이용해 피보나치 수열을 만들어 보면,
fibo = [1, 1]
for _ in range(D - 3):
fibo.append(fibo[-2] + fibo[-1])
# D=6 => fibo = [1, 1, 2, 3, 5]
D = 6, K = 41 이면,
A의 계수는 fibo[D-3] = 3
B의 계수는 fibo[D-2] = 5
=> 3A + 5B = 41
A는 1부터 K//A의 차수까지 가능하므로 반복문을 작성해 보면,
x, y = fibo[D-3], fibo[D-2]
for A in range(1, K//x + 1):
remain = K - (x*A)
if remain % y == 0:
B = remain // y
print(A)
print(B)
break
코드
D, K = map(int, input().split())
fibo = [1, 1]
for _ in range(D - 3):
fibo.append(fibo[-2] + fibo[-1])
# fibo = [1, 1, 2, 3, 5, 8, 13, ...]
# print(fibo)
x, y = fibo[D-3], fibo[D-2]
for A in range(1, K//x + 1):
remain = K - (x*A)
if remain % y == 0:
B = remain // y
print(A)
print(B)
break
회고
계수가 피보나치 수열임을 확인하고 이를 fibo 리스트로 만들어 저장한 후 각각의 계수가 가진 값을 일반화하는 과정이 어려웠다. 반복문의 범위를 A를 기준으로 잡고(B로 해도 상관 없음) 그리고 만약 B가 해당 계수로 나누어떨어질 때 B가 정해진다는 것이 핵심!!
반복문을 작성하는 과정이 어제 푼 프로그래머스 카펫(완전 탐색)과 비슷한 느낌..?
'알고리즘 > 백준' 카테고리의 다른 글
[백준]2805 나무자르기(Python) (0) | 2024.01.06 |
---|---|
[백준]9663 N-Queen(Python) (1) | 2024.01.05 |
[백준]9095 1, 2, 3 더하기(Python) (0) | 2024.01.05 |
[백준]1182 부분수열의 합(Python) (2) | 2024.01.03 |
[백준]6603 로또(Python) (0) | 2024.01.03 |