本题链接:点击打开链接
题意:先给出一个整数n,表示有n组测试数据,接着是有n个数据,每一个数据都是介于1到107之间。要求的是每个数阶层的位数,也就是每个数字阶层的长度是多少?
解题思路:
1.直接暴力求解,但似乎数据真的实在是太大了,但只要稍微改进一下代码还是可以AC的,只是比较费时,本人用了889MS险过;由于数据比较大,所以得用double类型,有时候这也是一个小技巧。
代码1:
#include
#include
int main()
{
int t,i,k,n;
double w;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
s=1;
w=1;
for(i=2; i<=n; i++)
{
s=s*i;
if(s>=10) //每计算一次大于10了,就先计算已有位数,并且在同一个for循环里进行,可节约一点时间。
while(s>=10)
{
s/=10;
w++; //记录已有位数。
}
}
printf("%d\n",w);
}
return 0;
}
假设10^(x-1)<=a<10^x,那么显然a的位数为x位,又因为
log10(10^(x-1))<=log10(a)<(log10(10^x))
即x-1<=log10(a)
即(int)log10(a)+1=x
即a的位数是(int)log10(a)+1;
代码2.
#include
#include
#include
int main()
{
int t,i,n;
double w;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
w=1;
for(i=1;i<=n; i++)
w=w+log10((double)i);
printf("%d\n",(int) w);
}
return 0;
}
3.最近还发现了一作做法,那就是利用斯特林公式来做,公式是:log10(n!)=1.0/2*log10(2*PI*n)+n*log10(n/e);至于为什么来来的,有兴趣的朋友可以自己去查有关资料,不然记忆就好,和前面的第二种方法一样,有了公式就很简单了。
代码3:
#include
#include
#include
#define e 2.71828182
#define PI 3.141592654
int main()
{
int t;
int n;
double w; //斯特林数
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
w=(1.0/2*log10(2*PI*n)+n*log10(n/e));
printf("%d\n",(int) w+1); //记得+1,不能少。
}
return 0;
}
以上三种方法我推荐的是第二种和第三种,两个公式大家可以不必细究到底怎么来的,但一定要记住它,关键时刻很有用,希望能帮到一些朋友。