题目:写一个函数f(N),返回1到N之间出现的"1"的个数。
假设N=A*10^i + B*10^(i-1) + C,即A,B和C分别代表第i位的高位数值,当前位数值和低位数值。第i位上1的个数与A,B,C可能都有关。
当B > 1时,([0-A],1,*)<(A,B,C),一共是(A+1)*10^i个1,高位相关。
当B = 1时,([0-(A-1),1,*])<(A,B,C),[A,1,[0-C]] <= (A,B,C),一共是A*10^i+C+1个1,高位低位相关。
当B = 0时,([0-(A-1)],1,*)<(A,B,C),一共是A*10^i个1,高位相关。
程序1:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
int find_num( int N, int x) { int count = 0; int A, B, C, factor; factor = 1; while(N >= factor) { A = N / (factor * 10); B = N / factor % 10; C = N % factor; cout << "(A,B,C): " << "(" << A << "," << B << "," << C << ")" << endl; if(B > x) count += (A + 1) * factor; else if(B == x) count += A * factor + C + 1; else count += A * factor; factor *= 10; } return count; } |
程序2:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//解法二,通过找规律来实现 long long sum1s( long long n) { long long iCount = 0; long long iFactor = 1; long long iLowerNum = 0; long long iCurrNum = 0; long long iHigherNum = 0; while(n / iFactor != 0) { iLowerNum = n - (n / iFactor) * iFactor; iCurrNum = (n / iFactor) % 10; iHigherNum = n / (iFactor * 10); switch(iCurrNum) { case 0: iCount += iHigherNum * iFactor; break; case 1: iCount += iHigherNum * iFactor + iLowerNum + 1; break; default: iCount += (iHigherNum + 1) * iFactor; break; } iFactor *= 10; } return iCount; } |