이 글에서는 C++을 사용하여 이친수(이진 수 중 연속된 1이 없는 수)를 구하는 방법에 대해 설명하겠습니다. 이 문제는 알고리즘 문제 해결 능력을 기르기 위한 좋은 연습이 될 것입니다.
문제 설명
이친수는 0과 1로 구성된 이진수 중에서 연속된 1이 없는 숫자를 의미합니다. 예를 들어, 0, 1, 10, 100, 101 등은 이친수입니다. 하지만 11, 111, 1100 등은 이친수가 아닙니다. 주어진 자연수 n에 대해 n 자리 이친수가 몇 개 있는지 구하는 문제입니다.
입력
첫 번째 줄에 자연수 n (1 ≤ n ≤ 45)이 주어집니다.
출력
n 자리 이친수의 개수를 출력합니다.
문제 접근 및 풀이 방법
이 문제를 해결하기 위해 피보나치 수열의 성질을 이용하도록 하겠습니다. 이친수를 만드는 방법은 다음과 같이 나눌 수 있습니다.
- n 자리 이친수의 가장 왼쪽 비트가 0인 경우, 그 나머지 비트는 (n-1) 자리 이친수가 됩니다.
- n 자리 이친수의 가장 왼쪽 비트가 1인 경우, 그 다음 비트는 반드시 0이어야 하므로 나머지 비트를 (n-2) 자리 이친수로 표현하게 됩니다.
즉, 이친수의 개수는 다음과 같이 정의할 수 있습니다:
f(n) = f(n-1) + f(n-2)
여기서 f(n)은 n 자리 이친수의 개수를 뜻합니다. 초기값으로는 다음과 같이 설정할 수 있습니다.
- f(1) = 2 (0, 1)
- f(2) = 3 (00, 01, 10)
따라서 n개의 이친수를 구하려면 피보나치 수열을 계산하는 방법을 활용하면 됩니다. 이제, C++로 실제 코드를 구현해 보겠습니다.
코드 구현
#include <iostream>
using namespace std;
long long findBinaryFriend(int n) {
long long *dp = new long long[n + 1];
dp[1] = 2; // 1자리 이친수
dp[2] = 3; // 2자리 이친수
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
int main() {
int n;
cout << "자연수 n을 입력하세요 (1≤n≤45): ";
cin >> n;
if (n >= 1 && n <= 45) {
cout << n << "자리 이친수의 개수는: " << findBinaryFriend(n) << "입니다." << endl;
} else {
cout << "잘못된 입력입니다." << endl;
}
return 0;
}
코드 설명
위 코드는 주어진 n에 대해 n 자리 이친수의 개수를 계산하는 프로그램입니다. 먼저, 동적 배열을 생성하여 메모리를 할당하고 초기값을 설정합니다. 이후 3부터 n까지 반복하면서 각 자리수에 해당하는 이친수를 찾기 위해 이전 두 항을 더하는 방식으로 진행됩니다.
마지막으로, 메인 함수에서는 사용자로부터 n을 입력받고, 조건에 맞는 경우 이친수의 개수를 출력합니다. 어떤 경우든 메모리 관리를 위해 할당한 배열을 해제해야 하는 점을 잊지 마세요.
테스트 및 검증
위 코드를 작성한 후 테스트를 해보는 것이 중요합니다. 다음과 같은 입력값에 대한 결과를 확인해 보세요:
- n = 1: 결과는 2 (0, 1)
- n = 2: 결과는 3 (00, 01, 10)
- n = 3: 결과는 5 (000, 001, 010, 100, 101)
- n = 4: 결과는 8
- n = 5: 결과는 13
이와 같은 입력에 대해 올바른 결과가 출력되는지 확인해야 합니다. 각 n값에 대한 이친수를 직접 손으로 세어보면서 검증해보는 것이 좋습니다.
결론
이 클래스에서는 C++을 사용하여 이친수 문제를 해결하는 방법을 배웠습니다. 이 문제는 피보나치 수열과 동적 계획법의 좋은 예시입니다. 이 문제를 통해 알고리즘 문제 해결 능력을 키울 수 있으니, 여러 입력 값으로 연습해 보시기 바랍니다.