看了 http://blog.csdn.net/chszs/article/details/1524679
感觉效率很低,现使用原创的数学公式新算法,用D语言把找下一个最大数的时间控制在0.3秒以内,(数值范围:1-200,000)
效率是穷举法的1000倍以上。
/*
有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。
比如f(13)=6,现在f(1)=1,问下一个最大的f(n)=n的n是什么?
*/
module fn;
import std.stdio;
import std.math;
import std.datetime;
int[int] aa;
int[] Ac;
void main()
{
writeln("(D language) Please wait for some minutes,will found Next Fn(n) = n ,the n is:");
int pos,n =1,count;
StopWatch sw;
sw.start();
while(n <200000)
{
Ac =null;
aa =null;
pos = Fn(n);
if(n == pos)
{
count++;
writeln("n is: ",n, " Fn(n) is: ",pos);
if(count >1) break;
}
n++;
}
sw.stop();
writeln(" time :" , sw.peek().msecs," msecs");///1000.0
writeln(n," stop");
writeln("all ok!");
}
int Fn(int n)
{
int i,y;
int l;
for(int x =n;x>=1;x/=10)
{
y=x%10;
aa[i] =y;
Ac~=y;
i++;
}
int m = cast(int)(Ac.length -1);
int result,h;
h =aa[m];
if( n%gPow(m) == 0) return fnA(h,m);
else return fnA(h,m)+fnB(m-1);
}
int fnA(int h,int m)
{
if(h == 0) return 0;
else if(h==1) {if(m == 0) return 1; else return m*gPow(m-1)+1;}
else {if(m == 0) return 1; else return gPow(m)+h*m*gPow(m-1);}
}
int fnB(int m)
{
.......... // 代码略
return sum + fnB(m-1);
}
int gPow(int m)
{
return pow!(int,int)(10,m);
}
编译方法: ldc2 -m64 -O -release fn.d 或ldc2 -m64 -O -release -inline fn.d
/* test number ---------------穷举法,可用于测试上一个方法的结果-------------------------------------------
*/
int Fn_test(int n)
{
int total;
for(int i=0;i<=n;i++)
{
total += Count(i);
}
return total;
}
int Count(int n)
{
int num;
for(int t = n;t >=1;t=t/10)
{
if(t%10 == 1) num++;
}
return num;
}