Date:

1) 문제 링크

https://www.acmicpc.net/problem/3996

2) 접근

몇 번 끄적이다 보니… 구간 $[0, n]$에 속한 자연수 중 k진법으로 표현했을 때 뒤에서 2, 4, 6, …번째에 있는 자릿수가 모두 0인 것이 ‘k진법 = -k진법’의 필요충분조건임을 깨달았다. 그리고, n을 k*k진법으로 바꾸면 이를 만족하는 자연수의 개수를 바로 계산할 수 있을 것이라 생각했다.

3) 풀이

n, k = map(int, input().split())
k_sq_based_n = list()

while n:
    k_sq_based_n.insert(0, n%(k*k))
    n //= k*k

res = 0
for digit in k_sq_based_n:
    if digit >= (k-1):
        res += k-1
    else:
        res += digit
    res *= k

res //= k
res += 1
print(res)

image

처음으로 짠 코드인데… 예제 입력도 잘 맞아떨어지고 최소 입력(n=1, k=2 등)에 대해서도 잘 작동했다. 맞왜틀?
이후 몇 가지 입력을 더 넣어보던 중 27을 넣었을 때 9가 아니라 7이 나오는 것을 보았다. 코드를 가만히 살펴보다가 if digit >= (k-1)이 아니라 digit >= k로 빼줬어야 함을 깨달았다. digit > (k-1)이 더 깔끔하려나? 암튼.

n, k = map(int, input().split())
k_sq_based_n = list()

while n:
    k_sq_based_n.insert(0, n%(k*k))
    n //= k*k

res = 0
flag = 0 # k진법의 자릿수를 초과하는 자릿수가 있는지 검사. 있다면 1.
for digit in k_sq_based_n:
    if digit >= k:
        res += k
        flag = 1
    elif flag == 0:
        res += digit
    res *= k

res //= k
if(flag == 0):
    res += 1
print(res)

image

???????????????????????
알고 보니 flag의 위치가 틀렸던 거였다. 애초에 flag 올라갔으면 그 뒤 자릿수들을 고려하면 안 되는데 쓸데없이 고려해서 셌으니…

n, k = map(int, input().split())
k_sq_based_n = list()

while n:
    k_sq_based_n.insert(0, n%(k*k))
    n //= k*k

res = 0
flag = 0
for digit in k_sq_based_n:
    if flag == 0:
        if digit >= k:
            res += k
            flag = 1
        else:
            res += digit
    res *= k

res //= k
if(flag == 0):
    res += 1
print(res)

image

겨우 맞았네 ㅋㅋ

4) 피드백

다 풀고 찜찜한 느낌이 들었다. flag를 안 쓰고 푸는 법은 없을까?

Leave a comment