문제
어떤수 N이 1이 될 때까지 다음의 두 과정 중 하나를 반복적으로 선택하여 수행하려고한다. 단, 두번째 연산은 N이 K로 나누어떨어질 때만 선택할 수 있다.
1. N에서 1을 뺀다.
2. N을 K로 나눈다.
예를 들어 N = 17, K = 4일 경우
1) 17 - 1 = 16
2) 16 // 4 = 4
3) 4 // 4 = 1
전체 과정을 실행한 횟수는 3이 된다. 이는 N을 1로 만드는 최소 횟수이다.
나의 코드
# 1) N에서 1을 뺀다
# 2) N을 k로 나눈다.
# 1) N/K 가 나누어 떨어지는 경우 나눗셈 실행 (우선실행해야 횟수를 최소한으로 할 수 있다.)
# 2) 나누어떨어지지 않은 경우 -1 실행
N = 17
K = 4
count = 0
while N != 1:
if N % K != 0:
N = N - 1
count += 1
else:
N = N / K
count += 1
print(count)
나는 while 문을 사용하여 N이 1이 될때까지 반복문을 실행했다. 반복문을 실행하면서 N이 K와 나누어떨어지면 K로 나누고, K와 나누어떨어지지 않으면 -1을 하여 count는 횟수만큼 +1을 해주고 N은 계산 결과로 저장된다.
정답 코드
# N, K공백을 기준으로 구분하여 입력 받기
n, k = map(int, input().split())
result = 0
while True:
# N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기
# n을 k로 나눈 몫에 k를 다시 곱한다 -> n이 k로 나눠떨어지지 않을때 가장 가까운 나눠 떨어지는 수를 구할 수 있다.
target = (n // k) * k
# 총 연산을 수행하는 횟수 (result) - target 은 1을 처리한 개수를 한번에 구한 것이다.
result += (n - target)
n = target
# N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출
if n < k:
break
# K로 나누기
result += 1 # k를 나누는 연산을 수행하므로 1번 추가
n //= k
# 마지막으로 남은 수에 대하여 1씩 빼기
result += (n - 1)
print(result)
출처: github.com/ndb796/python-for-coding-test/blob/master/
문제풀이
(1) 설명
target = (n // k) * k
우리는 N이 K로 나누어떨어지는 수가 될때까지 -1을 해야한다. 위에 '나의 코드'에서도 동일하다. 위 식을 통하여 target 이라는 변수에는 N이 K로 나누어떨어지는 가장 가까운 수를 저장한다.
n이 17이고 k가 4일 경우 (17 // 4) * 4 = 16이 된다. K(=4)로 나누어떨어지는 가장 가까운 수가 구해졌다.
(2) 설명
result += (n - target)
result 는 총 연산 횟수를 저장하는 변수이다. 우리는 위에서 target 이라는 K로 나누어떨어지는 가장 가까운 수를 추출했다. 그러므로 (n - target)을 수행하게되면 -1을 수행한 횟수를 구할 수 있다.
(3) 설명
n = target
target 을 n에 저장한다. 이유는 위에서 설명했듯이, -1 를 수행한 이후 K로 나누어떨어지는 가장 가까운 수인 N이기 떄문이다.
(4) 설명
if n < k:
break
n 이 k 보다 작아진다면 더이상 연산을 수행할 수 없으므로 반복문을 탈출한다.
(5) 설명
result += 1 # k를 나누는 연산을 수행하므로 1번 추가
n //= k
현재 N은 K로 나누어떨어지는 수가 되었다. 그러므로 연산 횟수를 1번 추가하고 N을 K로 나눈다.
(6) 설명
result += (n - 1)
반복문 탈출 후, 마지막으로 실행된느 코드이다. 우리는 반복문을 n이 k보다 작아졌을 경우 탈출했다. n이 k로 더이상 나눌 수 없기 때문이다. 그러므로 n은 아직 1이 아니다. n이 만약 현재 3이라면 최종 연산 횟수에 2를 더해야한다. (3 - 1 = 2, 2 - 1 = 1)
'Algorithm > Problem Solving' 카테고리의 다른 글
[코딩인터뷰] 배열 - 배열 파티션 문제풀이 (0) | 2021.02.06 |
---|---|
[코딩인터뷰] 배열 - 주식을 사고팔기 가장 좋은 시점 문제풀이 (0) | 2021.02.05 |
[이것이 코딩테스트다] 그리디 - 큰 수의 법칙 문제풀이 (0) | 2021.02.04 |
[이것이 코딩테스트다] 다이나믹 프로그래밍 - 1로 만들기 문제풀이 (0) | 2021.02.03 |
[이것이 코딩테스트다] 다이나믹 프로그래밍- 개미전사 문제풀이 (0) | 2021.02.03 |