-
[AtCoder - ABC029 D] 1문제 풀이/AtCoder 2023. 6. 6. 22:05
난이도: 1393
태그
더보기- Recursion
- Divide and Conquer
풀이
1. 어떤 수 \( N \)에 있는 1의 개수를 세보자.
더보기\( N \)에 있는 1의 개수는, \( N \)을 계속 10으로 나누면서 1의 자리가 1인지 계속 봐주면 됩니다.
2. [1]을 조금 다르게 생각해보자.
더보기[1]에서 구하는 과정을 잘 생각해보면, (10 이상의 자리에 있는 1의 개수) + (1의 자리에 있는 1의 개수)로 표현할 수 있습니다.
3a. \( 0 \) 이상 \( N \) 이하의 모든 정수에 있는 1의 개수를 세는 방법
더보기\( f(n) \)를 \( 0 \) 이상 \( n \) 이하의 모든 정수에 있는 1의 개수라고 정의하고
\( g(n) \)을 \( n \)에 있는 1의 개수라고 정의해봅시다.
그럼, \( f(n) = f(n-1) + g(n) \)이라는 간단한 재귀식을 찾아볼 수 있습니다.
3b. \( 0 \) 이상 \( N \) 이하의 모든 정수에 있는 1의 개수를 [2]를 사용해 좀 더 빠르게 세는 방법
더보기10 이상의 자리에 들어가는 수는 \( 0 \) 이상 \( \left\lfloor \frac{N}{10} \right\rfloor \)가 됩니다.
그리고 이 수는 10가지 다른 1의 자리와 묶이므로 10번씩 등장하게 됩니다.
// 엄밀히는 마지막 수는 10번 미만 등장할 수는 있습니다. 이는 [4]에서 다룰 예정입니다.
즉, \( 10 \times f(\left\lfloor \frac{N}{10} \right\rfloor) \)가 됩니다.
1의 자리는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, ...라는 주기 10의 간단한 규칙을 가지고 있으므로,
이를 토대로 생각해보면 등장 횟수는 \( \left\lfloor \frac{N+9}{10} \right\rfloor \)회가 됩니다.
즉, \( f(N) = 10 \times f(\left\lfloor \frac{N}{10} \right\rfloor) + \left\lfloor \frac{N+9}{10} \right\rfloor \)입니다...?
4. [3a]와 [3b]를 묶어보자.
더보기3b의 주석에서 말했듯이, 10 이상의 자리에 들어가는 수를 계산할 때 마지막 수는 10번 등장하지 않을 수 있습니다.
이를 처리하기는 귀찮으니, 실제로 마지막 수도 10번씩 등장할 때만 위 식을 사용해봅시다.
마지막 수까지 10번 등장하기 위해서는, \( N = 10n + 9 \) 꼴이어야 합니다.
그러니 이 경우만 [3b]로 처리해줍시다.
다른 경우에는 그냥 [3a]로 처리해줘도 충분히 빠른 시간에 돕니다.
\( f \)가 10번 돌 때마다 /10이 되므로 log 시간이 유지되기 때문이죠.
5. 코드
더보기코드에서는 \( \left\lfloor \frac{N+9}{10} \right\rfloor \)가 아니라 \( \left\lfloor \frac{N+1}{10} \right\rfloor \)을 더해줬는데, \( N = 10n + 9 \)에서 동일한 값을 가지므로 걱정하지 않아도 됩니다.
앳코더의 옛날 문제는 출력이 NewLine으로 끝나지 않으면 WA 처리하므로 주의하세요!
'문제 풀이 > AtCoder' 카테고리의 다른 글
[AtCoder - ARC032A] ホリドッグ (1) 2024.01.10 [AtCoder - ABC195 E] Lucky 7 Battle (0) 2023.03.09 [AtCoder - AGC034 B] ABC (0) 2023.03.09 [AtCoder - ARC121 A] 2nd Greatest Distance (0) 2023.03.09 [AtCoder - ABC104 D] We Love ABC (0) 2023.03.08