https://www.acmicpc.net/problem/2201
2201번: 이친수 찾기
0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 들 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않
www.acmicpc.net
첫 번째 이친수부터 하나하나 차례로 찾아나가다 보면, K자리의 이친수의 개수는 피보나치 수열의 K번째 값과 같다는 것을 알 수 있다. 즉 값이 2^(n - 1)승인 이친수는 n번째 이친수이다. 또한 모든 이친수를 값이 2^k인 이친수의 합 꼴로 나타내면, k의 합이 곧 해당 이친수의 순서임을 알 수 있다. 따라서 이를 이용하면 K번째 이친수의 값을 빠르게 알 수 있다.
#include <cstdio>
typedef long long ll;
#define LEN 87
#define MAX_K 1000000000000000000
int main() {
// out: 이친수를 저장할 공간, is_print: 출력 여부를 저장할 플래그
bool out[LEN] = { false, }, is_print = false;
// 반복문에서 사용할 인덱스
int i = 2;
// fib: 피보나치 수를 저장할 공간, K: 찾을 이친수의 순서
ll fib[LEN] = { 1, 2 }, K;
// 피보나치 수열을 완성
do { fib[i] = fib[i - 1] + fib[i - 2]; } while (fib[i++] <= MAX_K);
// 찾을 이친수의 순서를 입력받은 뒤
scanf("%lld", &K);
// 피보나치 수열을 이용해 K번째 이친수를 계산
for (i = LEN - 1; i >= 0; i--) if (K >= fib[i]) {
K -= fib[i];
out[i] = true;
}
// 완성한 이친수를 출력
for (i = LEN - 1; i >= 0; i--) {
// 가장 큰 자리부터 한 자리씩 확인하며
is_print |= out[i];
// 처음으로 1이 나왔을 때부터 출력
if (is_print) printf("%d", out[i]);
}
// 개행 문자를 출력해 출력을 종료
printf("\n");
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
백준 19953번: 영재의 산책 (0) | 2022.05.04 |
---|---|
백준 14676번: 영우는 사기꾼? (0) | 2022.04.13 |
백준 2024번: 선분 덮기 (0) | 2022.04.13 |
백준 3151번: 합이 0 (0) | 2022.02.06 |
백준 23349번: 졸업 사진 (0) | 2022.02.03 |