알고리즘/문제 풀이

4150번: 피보나치 수

Themion 2021. 12. 22. 12:18

https://www.acmicpc.net/problem/4150

 

4150번: 피보나치 수

피보나치 수열은 다음과 같이 그 전 두 항의 합으로 계산되는 수열이다. 첫 두 항은 1로 정의된다. f(1) = 1, f(2) = 1, f(n > 2) = f(n − 1) + f(n − 2) 정수를 입력받아, 그에 해당하는 피보나치 수를 출력

www.acmicpc.net

모든 정답이 1000자를 넘지 않는다는 것은 곧 정답의 범위가 10^1000이라는 뜻이고, 이 수는 64비트로 나타낼 수 있는 범위를 초과한다. 따라서 자바나 파이썬에 존재하는 BigInt을 구현해서 문제를 풀어야 한다.

#include <cstdio>

#define MAX_LEN 500
#define MOD 100

// 매우 긴 두 수를 string 형태로 저장해 더한다
void add(char c[MAX_LEN], char a[MAX_LEN], char b[MAX_LEN]) {
    // 두 성분을 더했을 때 발생한 carry
    bool carry = false;
    // 두 수의 각 성분을 더한 값
    char add_ = 0;

    // 두 수의 각 자리를 더해 그 결과를 c에 차례로 저장
    for (int i = MAX_LEN - 1; i >= 0; i--) {
        add_ = a[i] + b[i] + carry;
        c[i] = add_ % MOD;
        carry = add_ / MOD;
    }
}

int main() {
    // 피보나치 수를 3개의 1차원 배열에 두 자리씩 나누어 저장한다
    char arr[3][MAX_LEN];
    // N: 구하고자 하는 피보나치 수의 순서, idx: arr을 출력할 때 사용할 인덱스
    int N, idx = 0;

    scanf("%d", &N);

    // 첫 두 개의 피보나치 수는 1임이 자명하다
    arr[1][MAX_LEN - 1] = arr[2][MAX_LEN - 1] = 1;
    // 세 번째 피보나치 수부터 차례로 계산
    for (int i = 3; i <= N; i++)
        add(arr[i % 3], arr[(i - 2) % 3], arr[(i - 1) % 3]);

    // 배열의 빈 공간은 건너뛴 다음
    for (; !arr[N % 3][idx]; idx++);
    // 첫 자리는 빈 공간을 공백을 넣어서, 나머지 자리는 0을 넣어서 출력
    printf("%hhd", arr[N % 3][idx++]);
    for (; idx < MAX_LEN; idx++) printf("%02hhd", arr[N % 3][idx]);

    printf("\n");

    return 0;
}

'알고리즘 > 문제 풀이' 카테고리의 다른 글

4307번: 개미  (0) 2021.12.22
4153번: 직각삼각형  (0) 2021.12.22
3613번: Java vs C++  (0) 2021.12.22
3190번: 뱀  (0) 2021.12.22
3182번: 한동이는 공부가 하기 싫어!  (0) 2021.12.21