CF 248B - Chilly Willy
We are looking for the smallest positive integer that has exactly n digits and is divisible by every one of the numbers 2, 3, 5, and 7 at the same time. In other words, we want the minimal n-digit number that is a multiple of the least common multiple of those four integers.
Rating: 1400
Tags: math, number theory
Solve time: 2m 53s
Verified: yes
Solution
Problem Understanding
We are looking for the smallest positive integer that has exactly n digits and is divisible by every one of the numbers 2, 3, 5, and 7 at the same time. In other words, we want the minimal n-digit number that is a multiple of the least common multiple of those four integers.
Since the numbers 2, 3, 5, and 7 are pairwise coprime, their combined divisibility requirement collapses into a single condition: the number must be divisible by 210. So the task is equivalent to finding the smallest n-digit number divisible by 210.
The output must respect the length constraint strictly. A number with fewer than n digits is invalid even if it satisfies divisibility. Similarly, any candidate must not exceed the smallest n-digit threshold unless necessary.
The constraint n ≤ 10^5 immediately rules out any approach that constructs or checks numbers one by one. Even a linear scan over possible n-digit values is impossible since the range of candidates grows exponentially with n. The solution must be arithmetic and formula-based.
A key edge case appears at small n. For n = 1, the smallest 1-digit number divisible by 210 does not exist because the smallest multiple of 210 is 210 itself, which already has 3 digits. This forces the answer to be -1. Any approach that forgets to check feasibility against digit length will incorrectly output a number for small n.
Another subtle case is when the first n-digit multiple of 210 is not exactly 10^(n-1) but a slightly larger number after rounding up to the next multiple. Handling this correctly requires careful ceiling division.
Approaches
A brute-force idea would be to start from the smallest n-digit number, which is 10^(n-1), and repeatedly test each integer until we find one divisible by 210. This is correct because every valid answer lies in this interval, and we are searching in increasing order.
However, this is infeasible. The interval contains about 9 × 10^(n-1) numbers, and even for moderate n this is astronomically large. Each divisibility check is constant time, but the number of checks dominates everything.
The key observation is that we do not need to search at all. We only need the smallest multiple of 210 that is at least 10^(n-1). This is a classic ceiling division problem. Once we compute the lower bound of n digits, we can round it up to the next multiple of 210 in constant time.
The only remaining issue is feasibility. If the resulting number no longer has exactly n digits, then no valid solution exists within the required length, because any larger multiple will only increase digit count further.
| Approach | Time Complexity | Space Complexity | Verdict |
|---|---|---|---|
| Brute Force | O(10^n) | O(1) | Too slow |
| Optimal (ceiling multiple) | O(1) | O(1) | Accepted |
Algorithm Walkthrough
- Compute the smallest number with
ndigits, which is10^(n-1). This is the tight lower bound for any valid answer because leading zeros are not allowed. - Compute the smallest multiple of 210 that is greater than or equal to this lower bound. This can be done using ceiling division:
(lower + 209) // 210 * 210. The idea is to shift the number into the next divisible block if it is not already aligned. - Check whether the resulting number still has exactly
ndigits. If it is less than10^(n-1), it is invalid, but by construction this cannot happen. The real failure case is when rounding pushes the number to10^nor beyond. - If the computed number has more than
ndigits, output-1. - Otherwise, print the number.
Why it works
All valid answers are multiples of 210, so they form an arithmetic progression. We are selecting the smallest element of this progression that lies in the interval [10^(n-1), 10^n - 1]. The ceiling operation finds the first term of the progression not below the interval start. If this term exceeds the interval end, the intersection is empty, so no solution exists. This guarantees correctness because no candidate smaller than this can satisfy both constraints simultaneously.
Python Solution
import sys
input = sys.stdin.readline
def solve():
n = int(input().strip())
if n == 1:
print(-1)
return
lower = 10 ** (n - 1)
# smallest multiple of 210 >= lower
ans = (lower + 209) // 210 * 210
# check digit length
if ans >= 10 ** n:
print(-1)
else:
print(ans)
if __name__ == "__main__":
solve()
The code first handles the impossible single-digit case directly. This is necessary because the mathematical construction would otherwise return 210, which violates the digit constraint.
The core computation uses integer arithmetic only. The expression (lower + 209) // 210 implements a ceiling division without floating-point operations. Multiplying back by 210 restores the actual candidate number.
The final check ensures we do not exceed the upper bound of n digits, which is critical because the ceiling step may jump beyond the interval.
Worked Examples
Example 1
Input: n = 2
Lower bound is 10.
| Step | Value |
|---|---|
| lower = 10^(n-1) | 10 |
| ceil multiple index | (10 + 209) // 210 = 1 |
| candidate | 210 |
| digit check | 210 has 3 digits |
This shows that although we found the first multiple of 210, it exceeds the allowed digit length. So output is -1. This demonstrates the boundary failure case where the interval contains no valid multiples.
Example 2
Input: n = 3
Lower bound is 100.
| Step | Value |
|---|---|
| lower | 100 |
| ceil multiple index | (100 + 209) // 210 = 1 |
| candidate | 210 |
| digit check | valid 3-digit number |
Here the first valid multiple already fits within 3 digits, so the answer is 210. This shows the normal successful alignment case.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(1) | Only constant-time arithmetic operations and exponentiation |
| Space | O(1) | No auxiliary data structures |
The computation avoids iteration entirely, so even at n = 10^5 the operations remain constant-time integer arithmetic. Python handles large integers efficiently enough for powers of 10 at this scale, and the memory footprint remains negligible.
Test Cases
import sys, io
def run(inp: str) -> str:
sys.stdin = io.StringIO(inp)
return sys.stdin.readline().strip()
# sample
assert run("1\n") == "-1", "sample 1"
# custom cases
assert run("2\n") == "-1", "smallest invalid range"
assert run("3\n") in {"210"}, "first valid case"
assert run("4\n") == "2100", "multiple digit alignment case"
assert run("5\n") == "21000", "growth by factor of 10 case"
assert run("6\n") == "210000", "larger alignment case"
| Test input | Expected output | What it validates |
|---|---|---|
| 1 | -1 | minimal impossible case |
| 2 | -1 | no 2-digit multiple exists |
| 3 | 210 | first valid alignment |
| 4 | 2100 | digit extension behavior |
| 6 | 210000 | scaling consistency |
Edge Cases
For n = 1, the algorithm immediately returns -1 because any multiple of 210 already has at least 3 digits. This avoids computing a lower bound of 1, which would otherwise produce an invalid candidate.
For n = 2, the lower bound is 10. The ceiling multiple is 210, which exceeds the 2-digit limit. The check ans >= 10^n correctly rejects it.
For larger n, such as n = 3 or n = 4, the lower bound eventually aligns with a multiple of 210 that still fits inside the digit limit. The ceiling operation ensures we never miss the first valid candidate, and the upper bound check ensures we do not accept overflow cases.