def calc(n,t):
cnt=1
while n!=0:
while n%10 !=9:
if n!=0:
for i in str(n):
s_i[int(i)]+=cnt
n-=1
else:
return
if n<10:
for i in range(n+1):
s_i[i]+=cnt
s_i[0]-=cnt
return
else:
for i in range(10):
s_i[i]+=(n//10+1)*cnt
s_i[0]-=cnt
cnt*=10
n=n//10
return
N=int(input())
s_i=[0]*10
calc(N,s_i)
print(*s_i)
수학과 관련된 문제이다. 어려웠다.
www.slideshare.net/Baekjoon/baekjoon-online-judge-1019
자세한 설명은 백준님의 설명을 보면 되겠다.
1 ~ N 까지인데, 이걸 A~B로 보고
A는 0을 끝자리로 B는 끝자리를 9로 맞춰준고 계산을 하는거다.
만약 A가 3827 B가 9257 이라 하면
A 를 3830으로 맞춰주고, B를 9249로 맞춰준다 이렇게 됬을시, 1의 자리의 개수는
0~9 까지 총 (924-383+1)개 만큼이 나온다. 이걸 결과값에 누적을 시켜놓고 A,B를 10으로 나눈 몫으로 바꿔준다.
그러면 A는 383 B는 924가 되는데, 이걸 다시 A는 끝자리를 0으로 B는 9로 맞춰준다.
위와 같이하면 A는 390 B는 919가 된다.
여기서 기본 개수인 cnt를 기존의 1에서 10배가 되어야하는데 그 이유는 십의 자리이기 때문이다.
가볍게 생각해보면 우리가 11~39 까지라고 했을시 십의 자리는 1~3 이다. 하지만 그 사이에 나온 숫자는 총 30개이다.
이렇듯 자리수에 따라 10배씩 해주면 된다.
이와 같은 방식으로 하면서 A의 수가 B를 넘어가게 되면 멈추면 된다.
위의 코드는 과거에 푼 코드로, A를 0으로 고정해놓고 푼 방식이다. 그렇다 보니 매 번 0의 자리 수의 개수를 현재의 cnt만큼 빼주는 것이다.
def calc(number,cnt):
global number_list
while number > 0:
number_list[number%10] += cnt
number = number//10
def solution(start,end):
global number_list
cnt = 1
while start <= end:
if start%10 != 0:
while start % 10 != 0 and start <= end:
calc(start,cnt)
start += 1
if start > end:
break
if end%10 != 9:
while end % 10 != 9 and start <= end:
calc(end,cnt)
end -= 1
distance = (end//10 - start//10 + 1)
for i in range(10):
number_list[i] += distance * cnt
cnt *= 10
start = start//10
end = end//10
N = int(input())
start = 1
number_list = [0]*10
solution(start,N)
print(*number_list)
백준님의 설명대로 짤 시 오히려 더 간단하게 풀리는걸 알 수 있다.
위의 코드는 백준님의 설명대로 짠 코드이다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 1158 요세푸스 문제 (0) | 2021.02.23 |
---|---|
[BOJ/백준] 1067 이동 (2) | 2021.02.23 |
[BOJ/백준] 13398 연속합 2 (0) | 2021.02.22 |
[BOJ/백준] 2660 회장 뽑기 (0) | 2021.02.22 |
[BOJ/백준] 13023 ABCDE (0) | 2021.02.21 |