이 문제는 등차수열에 대해 다시 복습하고 푸니까 훨씬 잘 풀렸다.
우선 나는 이 문제를 한수인지 판별하는 함수를 만들어 카운트를 세는 방법으로 구현했다.
문제의 '한수 판별 함수'의 경우 3가지 포인트에 유의하며 접근했다.
포인트 1. 숫자가 1개만 있는 것도 수열이 성립한다(예: 1, 2, 3, 4...8, 9). 'an = a1 + (n-1)d' 이 식에 n=1을 대입해보면 성립한다는 것을 확인할 수 있다.
포인트 2. 10<=n<=99 구간에서는 공차가 0인 등차수열의 존재를 생각해야 한다. (Ex. 11, 22...)
포인트 3. 등차수열의 n차 항을 구하는 방법은 an = a1 + (n-1)d 이다. 자리수들 간에 이 관계가 성립하는지 확인하자.
# 1065 한수
# 한수인지 판별하는 함수를 만들어 문제를 풀어보자!
# 포인트 1. 숫자가 1개만 있는 것도 수열이 성립한다.
# 포인트 2. 10<=n<=99 구간에서는 공차가 0인 등차수열의 존재를 생각해야 한다.
# 포인트 3. 등차수열의 n차 항을 구하는 방법은 a(n) = a(1) + (n-1)d이다.
# 자리수들 간에 이 관계가 성립하는지 확인하자.
import math
def check(n):
arr = []
# 자리수만 가변 리스트에 넣기
log_num = math.trunc(math.log10(n))
while log_num >= 0:
arr.append((n // (10 ** log_num)))
n %= (10 ** log_num)
log_num -= 1
# 가변 리스트에 넣은 숫자들의 공차가 일정한지 확인해본다.
# 먼저 arr[1] - arr[0]으로 공차(d)를 초기화하고,
# 반복문을 돌리며, 나머지 숫자들의 차가 d와 일치하는지 확인한다.
d = arr[1] - arr[0]
result = True
for z in range(len(arr) - 1, 1, -1):
if arr[z] - arr[z-1] != d:
result = False
break
return result
N = int(input())
if 0 < N and N < 10:
print(N)
else:
cnt = 9
for i in range(10, N+1):
if check(i) == True:
cnt += 1
print(cnt)
반환할 값의 초기값을 True로 해두고, d에 arr[1] - arr[0]을 초기값으로 넣어 자리수간의 차가 하나라도 다르다면, 자리수가 등차수열(즉, 한수) 이 아닌 것이니 반환값을 False로 바꾸고 break로 반복문을 빠져 나오도록 했다.
조건문은 2가지 케이스로 나누었는데, ⅰ) 입력값이 1에서 9 사이일 때, ⅱ) 입력값이 10에서 1000 사이일 때 였다. 입력값이 10보다 작은 숫자라면 어차피 숫자 하나 하나가 등차수열이므로 들어온 수 그대로 출력해주면 된다. 입력값이 10에서 1000 사이일 경우 내가 만들어 둔 한수 측정 함수로 한수의 개수를 측정했다. 이때, count의 초기값에는 1-9를 이미 넣어 9를 넣어주었다.
푸는 도중에, 인덱스 에러가 계속 나서 왜 이러나 했는데, len(arr)을 초기값으로 지정할 때 len(arr) - 1을 안해준데다,
함수 밖의 반복문 iterator로 i를 썼으면서, 함수 안의 반복문에도 i를 쓰고 있었다...! 그래서 급하게 함수 안의 iterator은 z로 바꿔주었다.
그리고 하나라도 틀리면 result False로 바꿔주고 바로 반복문 나가버리도록 break를 추가해줬더니 매끈히 잘 동작했다!
'개발 공부 > 알고리즘 문제풀이' 카테고리의 다른 글
[백준] 11720. 숫자의 합 (0) | 2022.07.18 |
---|---|
[백준] 11654. 아스키 코드 (0) | 2022.07.18 |
[백준] 4673. 셀프 넘버 (0) | 2022.07.18 |
[백준] 15596. 정수 n개의 합 (0) | 2022.07.18 |
[백준] 4344. 평균은 넘겠지 (0) | 2022.07.18 |