이친수
https://www.acmicpc.net/problem/2193
2193번: 이친수
0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 중 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않
www.acmicpc.net
문제
0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 중 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다.
- 이친수는 0으로 시작하지 않는다.
- 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11을 부분 문자열로 갖지 않는다.
예를 들면 1, 10, 100, 101, 1000, 1001 등이 이친수가 된다. 하지만 0010101이나 101101은 각각 1, 2번 규칙에 위배되므로 이친수가 아니다.
N(1 ≤ N ≤ 90)이 주어졌을 때, N자리 이친수의 개수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N이 주어진다.
출력
첫째 줄에 N자리 이친수의 개수를 출력한다.
예제 입력 1
3
예제 출력 1
2
코드 1
N = int(input())
d = [[0] * 2 for _ in range(N+1)]
for i in range(1, N+1):
if i == 1:
d[1][0] = 0
d[1][1] = 1
else:
if d[i-1][1] != 0:
d[i][0] += d[i-1][1]
if d[i-1][0] != 0:
d[i][0] += d[i-1][0]
d[i][1] += d[i-1][0]
print(sum(d[N]))
풀이 1
n = 1일 때 1 n = 2일 때 10 n = 3일 때 100, 101 n = 4일 때 1000, 1001, 1010 n = 5일 때 10000, 10001, 10010, 10100, 10101 ... |
해당 문제는 2가지 풀이 방식으로 풀었다. 1번째 코드, 풀이를 우선 살펴보겠다.
2차원 배열 d를 생성하고, d[i][j]에서 i는 자릿수, j는 해당 숫자의 맨 마지막 수를 나타낸다. j가 중요한 이유는 이친수의 경우 맨 마지막 수가 0, 1이냐에 따라 뒤에 올 수 있는 수가 달라지기 때문이다.
i = 1인 경우(자릿수가 1일 때), d[1][0]은 한 자리수이고, 맨 마지막 수가 0인 이친수는 없다. 왜냐하면 이친수의 1번째 성질이 0으로 시작하지 않기 때문이다. d[1][0]은 한 자리수이고, 맨 마지막 수가 1인 이친수이며 가짓수는 1가지이기 때문에 1을 할당한다.
i가 1이 아닌 경우,
첫 번째 if문은 이전 자리수에서 1로 끝나는 수가 있는지 없는지 살펴본 후, 해당 자릿수의 이친수를 구해주는 구문이다. 1로 끝나면 그 뒤에 올 수 있는 수는 0밖에 없기 때문에 d[i][0]에 d[i-1][1]을 더해준다. 즉, 이전 자리수에서 1로 끝나는 수의 개수만큼 다음 자리수에서 0으로 끝나는 개수를 더해준다.
두 번째 if문은 이전 자리수에서 0으로 끝나는 수가 있는지 없는지 살펴본 후, 해당 자릿수의 이친수를 구해주는 구문이다. 0으로 끝나면 그 뒤에 올 수 있는 수는 0, 1 둘 다 가능하기 때문에 0, 1인 경우를 나누어 계산해준다.
코드 2
n = int(input())
d = [0] * (n+1)
d[1] = 1
for i in range(2, n+1):
if n == 1:
print(1)
else:
d[i] = d[i-1] + d[i-2]
print(d[n])
풀이 2
해당 문제를 1차원 배열로 풀 수 없나 고민하다가 한 가지 규칙을 발견하였다.
n = 4일 때, 하늘색 화살표를 보면 n = 2인 경우의 수와 n = 3인 경우의 수가 전부 포함되어 있다.
n = 5일 때, 빨간색 화살표를 보면 n = 3인 경우의 수와 n = 4인 경우의 수가 전부 포함되어 있다.
따라서, d[i] = d[i-1] + d[i-2]라는 점화식을 도출할 수 있다.
보다 자세한 설명은 https://cijbest.tistory.com/17 에서 참고하면 된다.
'Python > Coding Test' 카테고리의 다른 글
[백준] 2156 : 포도주 시식 (파이썬 / Python) (0) | 2023.07.17 |
---|---|
[백준] 9465 : 스티커 (파이썬 / Python) (0) | 2023.07.17 |
[백준] 11057 : 오르막 수 (파이썬 / Python) (0) | 2023.07.13 |
[백준] 10844 : 쉬운 계단 수 (파이썬 / Python) (0) | 2023.07.13 |
[백준] 9095 : 1, 2, 3 더하기 (파이썬 / Python) (0) | 2023.07.13 |