값이 길어져서 unsigned long long 으로도 커버가 안되는 문제다. 
string 끼리의 덧셈으로 풀어야 한다. 올림이 발생하면, 다음 자리수의 덧셈에 올림 수를 더해주는 연산이 필요하다. 
다른 분들의 풀이 포스팅을 읽고 이해했다. 다시 풀어 볼 문제. 
 
 
#include <bits/stdc++.h>
using namespace std;

int n, sum;
string a, b, tmp, fibo[10002];
vector<int> ans, num1, num2;

string big_num_sum(string s1, string s2){

  string s = "";

  // 더 긴 수를 s1에 저장한다.
  if(s1.size() < s2.size()) swap(s1, s2);

  // num1, num2 배열을 만든다.
  num1.push_back(0);
  num2.push_back(0);

  // s1이 더 긴 수니까. 그대로 num1 벡터를 채운다.
  for(int i = 0; i < s1.size(); i++)
    num1.push_back(s1[i] - '0');

  // s2가 비교적 짧은 수니까. s1, s2 길이 차이만큼 0을 num2 벡터에 채운다.
  for(int i = 0; i < s1.size() - s2.size(); i++)
    num2.push_back(0);

  for(int i = 0; i < s2.size(); i++)
    num2.push_back(s2[i] - '0');

  // num1, num2 벡터 맨 뒤부터 앞쪽으로 덧셈을 하면서 ans 벡터에 저장
  for(int i = s1.size(); i > 0; i--){
    sum = num1[i] + num2[i];
    if(sum > 9){
      num1[i-1] += 1; // 올림 수 발생했으니까 1을 더해준다.
      sum -= 10;
    }
    ans.push_back(sum);
  }

  // 맨 앞자리수에 올림수가 넘어왔다면,
  if(num1.front() != 0) s.push_back('1');

  // ans 벡터 원소 순서를 거꾸로.
  reverse(ans.begin(), ans.end());
  // ans 벡터의 숫자를 순차 출력하여 문자열 s에 이어붙인다. 
  for(auto n : ans){
    s.push_back(n+48); // 문자로 저장해야 하니까 48을 더해준다.  
  }
  num1.clear(); num2.clear(); ans.clear();
  return s;
}

int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> n;

  fibo[0] = "0";
  fibo[1] = "1";

  for(int i = 2; i <= n; i++){
    fibo[i] = big_num_sum(fibo[i-1], fibo[i-2]);
  }
  cout << fibo[n];

  return 0;
}
 
 

다시 푼 코드 링크

#include <bits/stdc++.h>
using namespace std;

int input;
string a, b, answer; // 긴 숫자를 문자로 표현
vector<int> va, vb; // 연산을 위한 벡터

string fibo(string &a, string &b){
  string res = "";

  int diff_len = b.size()-a.size(); // 숫자 길이의 차이

  for(int i = 0; i < diff_len; i++) va.push_back(0);
  for(auto str : a) va.push_back(str - '0');
  for(auto str : b) vb.push_back(str - '0');

  int carry = 0;
  for(int i = vb.size()-1; i >= 0; i--){
    int temp_sum = va[i] + vb[i];

    if(carry == 1) { // 올림수가 있었다면, 더해주고. 다시 0 으로 돌려놓음
      temp_sum++;
      carry = 0;
    }
    if(temp_sum > 9){
      temp_sum %= 10;
      carry = 1;
    }
    res += (temp_sum + '0');
  }

  if(carry == 1) res += '1';
  reverse(res.begin(), res.end());
  va.clear(); vb.clear();

  return res;
}
// 숫자 + '0' == 문자
// 문자 - '0' == 숫자
int main(void){
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> input;

  a = "0", b ="1";

  if(input == 0) cout << 0;
  else if(input == 1) cout << 1;
  else{
    for(int i = 2; i <= input; i++){
      answer = fibo(a, b);
      a = b;
      b = answer;
    }
    cout << b;
  }
  return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

곱셈 백준 1629번 c++  (0) 2022.02.09
큰 수 A+B 백준 10757번 c++  (0) 2022.02.09
피보나치 수 5 백준 10870번 c++  (0) 2022.02.08
피보나치 수 백준 2747번 c++  (0) 2022.02.08
피보나치 수 3 백준 2749번 c++  (0) 2022.02.08

+ Recent posts