문제
피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다.
그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다.
이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n>=2)가 된다.
n=17일때 까지 피보나치 수를 써보면 다음과 같다.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597
n이 주어졌을 때, n번째 피보나치 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.
출력
첫째 줄에 n번째 피보나치 수를 1,000,000으로 나눈 나머지를 출력한다.
입력값이 무려 10^18이다. 이런 문제는 오버플로우를 방지하기 위해 출력값을 나누거나 해당 값을 구하는 과정에서
값이 반복되는 주기가 나타나기 마련이다.
그렇지 않다면...?
실제로 계산해보면 92번째 피보나치 수열은 7,540,113,804,746,346,429 으로
unsigned long long int로 오버플로우가 나지 않는 마지막 숫자이다.
그 이상은... 포기하자 분명 다른 방법이 있다.
처음에는 적정수까지 1,000,000으로 나눈 값을 보면서 주기를 찾으려 했지만 실패하고 인터넷을
검색하던중 '피사노 주기'라는 것을 알게 되었다.
출저 : acmicpc.net
이번 문제에서는 1,000,000으로 나는 값을 구하고 있으니 피사노 주기는 1,500,000 이다.
주기를 찾는 시도가 실패했다는 사실이 그다지 놀랍지 않다. 1,500,500에 한번씩 반복된다니... 피사노 주기를 알지 못하면
절대 풀지 못하는 문제임이 분명하다.
코드에서 중요한 포인트는 피보나치 수를 구하는 과정에서도 1,000,000으로 나눈 나머지 값을 사용해야 한다는 것이다.
어짜피 그 이상의 값은 사용할 일이 없을뿐더러 이 과정이 없으면 풀이과정에서 오버플로우가 발생해버린다.
'Programming > ACMICPC' 카테고리의 다른 글
ACMICPC 1022 소용돌이 예쁘게 출력하기 (0) | 2017.01.11 |
---|---|
ACMICPC 2941 크로아티아 알파벳 (0) | 2017.01.09 |
ACMICPC 10820 문자열 분석 (0) | 2017.01.08 |
ACMICPC 10824 네 수 (0) | 2017.01.08 |
ACMICPC 4344 평균은 넘겠지 (0) | 2017.01.06 |