※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 17840번 문제인 피보나치 음악이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/17840
17840번: 피보나치 음악
작곡가 철수는 피보나치 수열을 이용하여 만든 피아노 곡을 우연히 유튜브에서 보게 되었다. 피보나치 수열이란 f1 = 1, f2 = 1, fn+2 = fn+1 + fn (모든 n ≥ 1에 대해)을 만족하는 수열이다. 이 곡은 피
www.acmicpc.net
M의 제한이 1,000 이하인 것에 주목하자.
피보나치 수를 구하는 점화식을 관찰하면 새로운 항은 이전 두 항의 쌍에 의해 결정되는 것을 알 수 있다. 이러한 두 항의 쌍은 M의 제한이 1,000이므로 1,000*1,000 = 1,000,000가지밖에 존재하지 않게 된다.
따라서 많아봐야 100만개의 항을 구하면 피보나치 점화식은 어느 순간서부터 주기적으로 반복하는 모습을 보이게 될 것이다.
피보나치 수를 M으로 나눈 수열의 주기는 항상 초항을 포함하여 구성된다는 사실은 잘 알려져있다. 이 사실에 대해 더 알고싶다면 피사노 주기(Pisano period)에 대하여 조사해보자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
int M, Q;
string s = "";
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> Q >> M;
int x = 1, y = 1;
while (!(x == 0 && y == 1)) {
s += to_string(x);
int tmp = (x + y) % M;
x = y; y = tmp;
}
s += "0";
ll MOD = s.length();
while (Q--) {
ll q; cin >> q;
cout << s[(q - 1) % MOD] << '\n';
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 5570 // C++] 산타클로스와 루돌프 (0) | 2022.06.12 |
---|---|
[BOJ 17841 // C++] UNIST는 무엇의 약자일까? (0) | 2022.06.12 |
[BOJ 5569 // C++] 출근 경로 (0) | 2022.06.12 |
[BOJ 17843 // C++] 시계 (0) | 2022.06.12 |
[BOJ 1922 // C++] 네트워크 연결 (0) | 2022.06.11 |