A positive integer N is given. Consider the sequence of numbers [0, 1, ..., N]. What is the total number of zeros in the decimal representations of these numbers?

N can be very large. Hence, it is given in the form of a non-empty string S of length L, containing a decimal representation of N. S contains no leading zeros.

Write a function:

int number_of_zeros(char *S);
int number_of_zeros(const string &S);

that, given a string S, which is a decimal representation of some positive integer N, returns the total number of zeros in the decimal representations of numbers [0, 1, ..., N]. If the result exceeds 1,410,000,016, the function should return the remainder from the division of the result by 1,410,000,017.

For example, for S="100" the function should return 12 and for S="219" it should return 42.

Assume that:

* L is an integer within the range [1..10,000];
* string S consists only of digits (0-9);
* string S contains no leading zeros.

I tried to solve it and wrote the function but the running time complexity is more sophisticated than O(L) in my solution,
Can anyone solve it ( at least provide an algorithm or pseudocode or explanation )?

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

3

How would you solve this problem by hand, without a computer? I'm pretty sure that if you try to do so you will quickly stumble on some patterns...
–
hugomgNov 8 '11 at 12:40

there should be a way/algorithm to compute number of zeroes from decimal number inside the input string with complexity O(L) that I am trying to find ( using % , / -+,* operations ) I guess...
–
St ShtNov 8 '11 at 15:35

2 Answers
2

This problem is a good example of the strengths of recursion. Consider the simple base case: The numbers from 1 to 1 have exactly 0 zeroes.

When you have the numbers of zeroes in the numbers from 1 to N (say x), you can compute the numbers from 1 to N*10 as 9*x+log10(N*10). The argument is simple: You need nine blocks with an equal number of zeros for the numbers 1..., 2..., 3... and the number N*10 is written as 10000... .

This recursion is valid for all powers of 10. The recursion for arbitrary N is not much harder to compute when you split the number into the powers of 10 constituting it.

Thank thiton for your reply. Sorry I did not understand that "When you have the numbers of zeroes in the numbers from 1 to N (say x), you can compute the numbers from 1 to N*10 as 9*x+log10(N*10). The argument is simple: You need nine blocks with an equal number of zeros for the numbers 1..., 2..., 3... and the number N*10 is written as 10000... ." can you illustrate by code or drawing.Thanks.
–
St ShtNov 8 '11 at 19:26

Since there's only an upper limit of 10000, and this is technically a time-space complexity reduction contest just pre-compute all the possible answers in your submission code. You might notice this is very memory inefficient but with an observation that there is never a situation where any lookup value is more than 9 numbers away from a 'zero' you can use a dictionary to save a large amount of memory.

@missingno: 32k is almost always within this limit. I have submitted a 3.4 meg file as a submission before.
–
NoxvilleNov 8 '11 at 16:27

@StSht: It's essentially that, but better. Not every number increases the "zero-count", so you only store ones where there is a change. Then, if you need to lookup some query Q, you look to see if Q is in the dictionary (hashmap): if it is, you return the value, if it isn't, you decrease Q by 1 and try again.
–
NoxvilleNov 8 '11 at 16:29