본문 바로가기

Algorithm

[백준 알고리즘]1003번 피보나치 함수(Runtime error 해결)

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

 

1003번: 피보나치 함수

각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.

www.acmicpc.net

문제

다음 소스는 N번째 피보나치 수를 구하는 C++ 함수이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int fibonacci(int n) {
 
    if (n == 0) {
 
        printf("0");
 
        return 0;
 
    } else if (n == 1) {
 
        printf("1");
 
        return 1;
 
    } else {
 
        return fibonacci(n‐1) + fibonacci(n‐2);
 
    }
 
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

fibonacci(3)을 호출하면 다음과 같은 일이 일어난다.

  • fibonacci(3)은 fibonacci(2)와 fibonacci(1) (첫 번째 호출)을 호출한다.
  • fibonacci(2)는 fibonacci(1) (두 번째 호출)과 fibonacci(0)을 호출한다.
  • 두 번째 호출한 fibonacci(1)은 1을 출력하고 1을 리턴한다.
  • fibonacci(0)은 0을 출력하고, 0을 리턴한다.
  • fibonacci(2)는 fibonacci(1)과 fibonacci(0)의 결과를 얻고, 1을 리턴한다.
  • 첫 번째 호출한 fibonacci(1)은 1을 출력하고, 1을 리턴한다.
  • fibonacci(3)은 fibonacci(2)와 fibonacci(1)의 결과를 얻고, 2를 리턴한다.

1은 2번 출력되고, 0은 1번 출력된다. N이 주어졌을 때, fibonacci(N)을 호출했을 때, 0과 1이 각각 몇 번 출력되는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다.

각 테스트 케이스는 한 줄로 이루어져 있고, N이 주어진다. N은 40보다 작거나 같은 자연수 또는 0이다.

출력

각 테스트 케이스마다 0이 출력되는 횟수와 1이 출력되는 횟수를 공백으로 구분해서 출력한다.

풀이

이 문제에서 주의할 점은 주어진 피보나치 재귀함수를 사용하지 않는 것입니다. 단순 재귀를 사용하게 되면 런타임 오류가 뜨게 되서 계속 틀렸다고 나와요..

이 문제의 재밌는 점이 0이 출력되는 횟수와 1이 출력되는 횟수에도 피보나치 수열의 관계를 가지고 있다는 점입니다.

저는 이 규칙을 따라서 피보나치 함수로 배열을 만들어 준 뒤 알맞는 숫자를 출력하는 형태로 알고리즘을 짰습니다. 아래 코드를 보시면 N이 최대 40이라서 안전하게 41개의 배열을 생성해 피보나치 수를 넣었주었습니다.

이후 arr에 입력된 숫자를 count만큼 동적할당해 입력받은 뒤 출력을 한번에 하도록 반복문을 따로 짜줬어요. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<stdio.h>
#include<stdlib.h>
 
int fibonacci(int n) {
    int count_zero = 0;
    int count_one = 0;
    int fibo[41];
 
    fibo[0= 0;
    fibo[1= 1;
 
    for (int i = 2; i <= n; i++) {
        fibo[i] = fibo[i - 2+ fibo[i - 1];
    }
 
    if(n==0)
        printf("1 0\n");
    else
        printf("%d %d\n", fibo[n-1], fibo[n]);
    
    return 1;
}
 
 
int main() {
    int n, count;
    int* arr;
    scanf("%d"&count);
    arr = (int*)malloc(sizeof(int* count);
 
    for (int i = 0; i < count; i++) {
        scanf("%d"&n);
        arr[i] = n;
    }
    for (int i = 0; i < count; i++) {
        fibonacci(arr[i]);
    }
    free(arr);
    return 0;
}
 
 
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

백준 알고리즘의 예제 출력처럼 한번에 출력하기 위해선 이렇게 짜줬는데 한번 입력받고 하나 출력도 가능하네요. 이럴경우엔 동적할당 필요없고 이런 식으로 작성해주시면 됩니다.

1
for (int i = 0; i < count; i++) { scanf("%d", &n); fibonacci(n); }