This is a math problem, really. We have
1 ≤ k ≤ 1018 < 260
-1018 ≤ a ≤ b ≤ 1018
so we need inttypes.h
and int64_t
to be able to describe a and b; it'll also work for k. To scan the three values, the pattern "%" SCNd64 " %" SCNd64 " %d" SCNd64 ""
will work. To print, use pattern "%" PRId64 ""
. (The inttypes.h
header file that contains these was standardized in ISO C99, and is also defined in POSIX.)
The actual problem at hand is to find the number of unique integers n
for which
a ≤ n k ≤ b
where a and b are integers, and k is a positive integer. The smallest and largest n fulfill
a ≤ nmin k
b ≥ nmax k
that can be written also as
a ÷ k ≤ nmin
b ÷ k ≥ nmax
where ÷
denotes ordinary division. The number we need to print is the number of unique n, or
nmax - nmin + 1
If we use /
for integer division (as done in C, i.e. truncating division), ceil()
for ceil (rounding towards positive infinity), and floor()
for floor (rounding towards negative infinity), and we remember k is a positive integer, we can write the inequalities as
a ÷ k ≤ ceil( a ÷ k ) = nmin
b ÷ k ≥ floor( b ÷ k ) = nmax
and the number to be printed is
floor( b ÷ k ) - ceil( a ÷ k ) + 1
Although the standard C library provides functions ceil()
and floor()
in math.h
, they only work for floating-point numbers (but even double-precision floating point does not have integer precision over the range -1018 to +1018). Instead, we need to use integer rounding "tricks":
ceil( x ÷ k ) = (x + k - 1) / k, x > 0, k > 0
ceil( x ÷ k ) = x / k, x ≤ 0, k > 0
floor( x ÷ k ) = x / k, x ≥ 0, k > 0
floor( x ÷ k ) = (x - k + 1) / k, x < 0, k > 0
The only limitation here is that our integer type must be able to represent numbers from a-k to b+k, inclusive. Since int64_t
can represent range (roughly) -9.22×1018 to +9.22×1018, we're well covered.
For the actual solution program, you need to scan a, b, k (and I already mentioned the correct patterns for int64_t
), verify a ≤ b and k ≥ 1, calculate nmax and nmin using the above math, and finally print the result (again, I mentioned the printf pattern to use for int64_t
). It's very straightforward, if you have the math firmly in your grasp.