- 论坛徽章:
- 0
|
我的想法是得到数(abcdefg...)中某一位为1且不大于该数的数目, 遍例所有位, 求和得到0到数字abcdefg之间含有1的个数。f(n)函数时间复杂度是log10(n).
这里还少一个对最大数字判断的算法(淘汰部分马上可确认n != f(n)的数)
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- using namespace std;
- int f(int n)
- {
- int total = 0;
- int m = ((int) log10(n)) + 1; //m是n的数字位数
-
- int ax;
- float fn = (float) n;
- for (int x=0; x<m; x++) // 假设数字是[a0 a1 a2 ... ax ... am](a0,a1,a2...代表每一位)
- {
- int num = 0;
- ax = (int) (n / (int) pow(10, m-1-x)) % 10; //第x位的数
-
- int n_begin = (int) floor(fn /pow(10, m-x)); // ax之间的数字[a0...a(x-1)]
- switch (ax)
- {
- case 0: //0时 直接取[a0 a1 a2 .. a(x-1) 0 0 0...](m-x-1个0)
- {
- num = n_begin * ((int) pow(10, m-x-1));
- break;
- }
- case 1: //1 比0的情况多了[a(x+1) ... am]个数
- {
- num = n_begin * ((int) pow(10, m-x-1));
- int n_end = (int) floor(n % ((int) pow(10, m-x-1)));
- num = num + n_end;
- break;
- }
- default: // 其他的情况 为[a0 a1 a(m-1) + 1]*(10^(m-x-1))
- {
- num = (n_begin + 1) * ((int) pow(10, m-x-1));
- break;
- }
- }
- }
- if (total == n) printf("%d\n", n);
- return total;
- }
- int main()
- {
- for (int i=0; i<99999999; i++)
- {
- f(i);
- }
- return 0;
- }
复制代码
[ 本帖最后由 seaheart 于 2006-4-19 10:10 编辑 ] |
|