본문 바로가기

알고리즘

[js 알고리즘] 백준 9009: 피보나치

문제

피보나치 수 ƒK는 ƒK = ƒK-1 + ƒK-2로 정의되며 초기값은 ƒ0 = 0과 ƒ1 = 1 이다. 양의 정수는 하나 혹은 그 이상의 서로 다른 피보나치 수들의 합으로 나타낼 수 있다는 사실은 잘 알려져 있다. 

하나의 양의 정수에 대한 피보나치 수들의 합은 여러 가지 형태가 있다. 예를 들어 정수 100은 ƒ4 + ƒ6 + ƒ11 = 3 + 8 + 89 또는 ƒ1 + ƒ3 + ƒ6 + ƒ11 = 1 + 2 + 8 + 89, 또는 ƒ4 + ƒ6 + ƒ9 + ƒ10 = 3 + 8 + 34 + 55 등으로 나타낼 수 있다. 이 문제는 하나의 양의 정수를 최소 개수의 서로 다른 피보나치 수들의 합으로 나타내는 것이다. 

하나의 양의 정수가 주어질 때, 피보나치 수들의 합이 주어진 정수와 같게 되는 최소 개수의 서로 다른 피보나치 수들을 구하라. 

입력

입력 데이터는 표준입력을 사용한다. 입력은 T 개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 테스트 데이터의 수를 나타내는 정수 T 가 주어진다. 각 테스트 데이터에는 하나의 정수 n이 주어진다. 단, 1 ≤ n ≤ 1,000,000,000. 

출력

출력은 표준출력을 사용한다. 하나의 테스트 데이터에 대한 해를 하나의 줄에 출력한다. 각 테스트 데이터에 대해, 피보나치 수들의 합이 주어진 정수에 대해 같게 되는 최소수의 피보나치 수들을 증가하는 순서로 출력한다. 


피보나치 수란?

첫째 및 둘째 항이 1이며, 그 뒤의 모든 항은 바로 앞 두항의 합인 수열이다. 

즉, [0,1]이 존재할 때, 0+1=1,1+1=2,1+2=3,2+3=5 이런 식으로 수열이 생성된다.

 

피보나치 수를 갖는 알고리즘은 아래와 같다. n=1,000,000,000이므로 1e9만큼 생성하게 제작하였다.

const getPibo = () => {
  const pibo = [];
  pibo.push(0, 1);
  while (pibo[pibo.length - 1] < 1e9)
    pibo.push(pibo[pibo.length - 2] + pibo[pibo.length - 1]);
  return pibo;
};

 

여러개의 수가 존재하기 때문에 for문을 이용하여 돌려주었고, while문을 이용하여 해당 수의 piboList를 만들었다.

const getPiboList = (pibo, input) => {
  const testCase = Number(input[0]);
  for (let i = 1; i <= testCase; i++) {
    let n = Number(input[i]);
    let answer = [];
    let piboIndex = pibo.length - 1;

    while (n > 0) {
      if (n >= pibo[piboIndex]) {
        n -= pibo[piboIndex];
        answer.push(pibo[piboIndex]);
      }
      piboIndex--;
    }
    console.log(answer.reverse().join(" "));
  }
};

 

참고

 

피보나치 수 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 피보나치 수를 이용한 사각형 채우기 수학에서 피보나치 수(영어: Fibonacci numbers)는 첫째 및 둘째 항이 1이며 그 뒤의 모든 항은 바로 앞 두 항의 합인 수열이다.

ko.wikipedia.org