Topic:
Given a positive integer in decimal, write down all integers starting with 1, to N, and then count the number of "1" that appears.
Requirements:
Write a function f (n) that returns the number of "1" that occurs between 1 and N. For example F (12) = 5;
Within a 32-bit integer range, what is the maximum n of "f (n) =n" that satisfies the condition?
Design ideas:
(Solution one)
began to think of the simplest way to calculate f (N), that is, from 1 to start traversing, until the end of N, each of which contains the number of "1" added together, the result is from 1 to N all "1" and the number of the. This method is very simple, but the implementation efficiency of the algorithm is a big problem, if n is large, it takes a long time to calculate the results.
(Solution II)
Find some information, found that this is also the beauty of programming a problem, get a little inspiration. Let's start by listing some of the numbers, and find the hidden patterns:
One number: F (0) =0, f (1) =1, F (2~9) =1
The two-digit number (in the case of the number of digits is 3, [10 bit]+[digit]):
F (13) =4+2= 6, F (23) =Ten+3=13 ... f (93) =Ten+ Ten=20
The analysis found that the number of single-digit 1 and single digit and 10-digit number is related to: if the single digit of n is greater than or equal to 1, then the number of digit 1 is 10 digits plus 1; If the number of single digit of n is less than 1, then the number of digit 1 is 10 digits. 10 bits appear 1 times: if 10 digits equals 1, 10 bits appear with 1 digits plus 1, and if 10 digits are greater than 1, 10 bits appear 1 times.
Three-digit number ([Hundred]+[10 bit]+[digit]):
F (3) =4+10+ one= 25, F (113) = +14+= 40, F (1 2 3) =+20+ =57...
F (193) =94+20+= 134, F (3) =100+20+ The ...
Analysis of four-digit, five-digit numbers ...
(1)
Source:
#include <iostream.h>intFintN) { intI,unit,decade; intCount=0; for(i=1; i<=n;i++) {Decade=i; while(decade!=0) {Unit=decade%Ten; Decade=decade/Ten; if(unit==1) {Count++; } } } returncount;}voidMain () {intN,count; cout<<"Please input N:"; CIN>>N; Count=f (n); cout<<"From 1 to"<<n<<", there is"<<count<<"ones."<<Endl;}
View Code
Operation Result:
(2)
Source:
#include <iostream>#include<cstdio>using namespacestd;intFintN) { intFactor=1; intCount=0; intHigh=0; intCurrent=0; intlow=0; while(n/factor) { Low=n%factor; Current=n/factor%Ten; High=n/factor/Ten; Switch(current) { Case 0: Count+=high*factor; Break; Case 1: Count+=high*factor+low+1; Break; default: Count+ = (high+1)*factor; Break; } Factor*=Ten; } returncount;}intMain () {intN; while(SCANF ("%d", &n)! =EOF) {cout<<f (n) <<Endl; } return 0;}
View Code
Operation Result:
Summarize:
If only the basic function is required, then the reality is not very difficult, the key is that when N becomes very large, traversal is not a good way, then we must find the hidden law, like the primary School Olympiad, in a column of numbers, each case is taken apart, and then analyzed, to find the hidden law. The discovery of the D process may be a lot of things to find out, and it is certain that the first rule found is correct. Not until confirmed, but also continue to expand, four-digit, five-digit, six-digit number ... Even larger, and also the uncertain N, requires that it be arbitrary, universal, rather than just a special number, similar to "ABCDE".
Recently the teacher gave the topic from the "programming of the United States" inside, the topic is typical, mainly is to pay attention to ideas and algorithms, have the opportunity to see this book.
Class Assignment--Find 1