mojo's Blog

[백준 2201] 이친수 찾기 본문

백준/Dynamic Programming

[백준 2201] 이친수 찾기

_mojo_ 2021. 7. 19. 20:20

문제 링크 => 2201번: 이친수 찾기 (acmicpc.net)

 

2201번: 이친수 찾기

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 들 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않

www.acmicpc.net


다이나믹 프로그래밍 문제이다.

 

이친수는 다음과 같은 성질을 갖는다고 한다.

  1. 이친수는 0으로 시작하지 않는다.
  2. 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11을 부분 문자열로 갖지 않는다.

예를 들어서 1, 10, 100, 101, 1000, 1001, 1010, 10000, ... 와 같은 숫자들이 이친수이다.

 

그렇다면 이 숫자들을 나열하여 규칙성을 찾아보면 다음과 같은 규칙이 나온다는것을 확인할 수 있다.

 

1 => m[1]=1

10 => m[2]=2

100 => m[3]=3

101

1000 => m[4]=5

1001

1010

10000 => m[5]=8

10001

10010

10100

10101

100000 => m[6]=13

 

맨 앞자리가 1이고 나머지 숫자가 전부 0일 때 몇번째인지를 판단해 보면 m[x] = m[x-1] + m[x-2]; 식이 나온다.

 

즉, 피보나치 수열을 통해 맨 앞자리가 1이고 나머지 숫자가 전부 0일때 몇번째 숫자인지를 확인 가능하다.

 

그렇다면 m[x]를 통해 어떻게 숫자를 찾아낼 수 있을까? 이 규칙은 다음과 같다.

 

예를들어서 10101 을 살펴보도록 하면, m[5] + m[3] + m[1] = 12 번째 숫자이다.

 

이를 역으로 접근해야 하므로 다음과 같은 방법으로 찾아줘야 한다.

  1. 처음으로 m[x] < k < m[x+1] 를 만족하도록 하는 x를 찾는다.
  2. k = k - m[x] 를 해준다.
  3. k > 0 인 경우 1번으로 돌아가고 0인 경우 반복을 멈춘다.

풀이 code

#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <time.h>
#define INF 100000000
#define endl '\n'
#define MOD 1000000009
#define ll long long

using namespace std;

ll k;
ll memo[88];

void dp() {
	memo[1] = 1, memo[2] = 2, memo[3] = 3;
	for (ll idx = 4; memo[idx-1] < 1000000000000000000; idx++) {
		memo[idx] = memo[idx - 1] + memo[idx - 2];
	}
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	dp();
	cin >> k;
	int maxNum = 0;
	map<int, int> m;
	while (k != 0) {
		int idx;
		for (int i = 1; i <= 87; i++) {
			if (memo[i] > k) {
				idx = i - 1;
				maxNum = max(maxNum, idx);
				k -= memo[idx];
				break;
			}
		}
		m[idx]++;
	}

	for (int i = maxNum; i >= 1; i--) {
		if (m[i]) cout << 1;
		else cout << 0;
	}

	return 0;
}

'백준 > Dynamic Programming' 카테고리의 다른 글

[백준 22358] 스키장  (0) 2021.08.06
[백준 11049] 행렬 곱셈 순서  (0) 2021.07.27
[백준 2662] 기업투자  (0) 2021.07.13
[백준 2533] 사회망 서비스(SNS)  (0) 2021.07.13
[백준 2248] 이진수 찾기  (0) 2021.07.13
Comments