http://acm.hdu.edu.cn/showproblem.php?pid=1018
这个题目好像还是在11年暑假看的呢,一直想用那个大整数乘法把N!求出,然后再用一个strlen函数求出位数,可是一直比较懒,都不愿意写,今天看书的时候,发现书上的讲解太牛了,虽然我不是很懂,还是拿来和大家分享一下吧。
思路1. 这道题可以采用蛮力法,根据定义,直接求解。所谓N!位数,就是lg(N!)+1(不是很懂),根据数学公式: N ! = 1*2*3……N <==> lg(N!)=lg(2)+lg(3)+……+lg(n);
所以呢 代码如下
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<math.h>
5 using namespace std;
6 int main()
7 {
8 int n,t;
9 long double sum,i; //这里之所以用 long double是因为log10(参数)这个参数默认的是long double型的
10 cin>>t;
11 while(t--)
12 {
13 sum=0.0;
14 cin>>n;
15 for(i=2;i<=n;i++)
16 {
17 sum+=log10(i);
18 //cout<<sum<<endl;
19 }
20 printf("%d\n",((int)sum+1));
21 }
22 return 0;
23 }
思路2. 这类题,如果计算量比较大时,往往需要数学方面的知识,减少计算量,当然这就不属于蛮力法了。本题还可以采用Stirling公式,在n较大时,可以大大减少计算量
Stirling公式 n!= sqrt(2* pai * n)*(n/e)^n;(由于不会打开方号,所以就用sqrt代表开方的意思了) 所以 lgn!约等于 (lg( 2 * pai ) + lgn) / 2 +n *(lgn-lge)。
AC代码如下
// c1 = lg (2 * pai), c2 = lge
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<math.h>
5 using namespace std;
6 int main()
7 {
8 long double n,s,c3;
9 long double c1=0.798179868358,c2=0.434294481903;
10 int t;
11 cin>>t;
12 while(t--)
13 {
14 cin>>n;
15 c3=log10(n);
16 s=1;
17 if(n>3)
18 s=(c3+c1)/2+n*(c3-c2)+1;
19 printf("%d\n",(int)s);
20 //cout<<s<<endl;
21 }
22 return 0;
23 }
思路3.就是用大整数先求出n的阶乘,然后再用一个strlen函数求长度。耗时挺长的,仅供参考
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define M 70000000
char str[M];
int a[M],b[M],c[M];
void ca(int n)
{
int i;
int k;
str[0]='1';
str[1]='1';
int len=1;
for(i=2;i<=n;i++)
{
int j=0;
for( k=len-1;k>=0;k--)
a[j++]=str[k]-'0';
int temp=i;
int g=0;
while(temp)
{
b[g++]=temp%10;
temp/=10;
}
memset(c,0,sizeof(c));
for(k=0;k<len;k++)
{
for(j=0;j<g;j++)
{
c[j+k]+=(a[k]*b[j]);
if(c[j+k]>9)
{
c[j+k+1]+=(c[j+k]/10);
c[j+k]%=10;
}
}
}
k=len*g;
while(!c[k]) k--;
int h=0;
for(j=k;j>=0;j--)
{
str[h++]=(c[j]+'0');
}
len=h;
}
}
int main()
{
memset(str,0,sizeof(str));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
int n,t;
cin>>t;
while(t--)
{
cin>>n;
ca(n);
int len=strlen(str);
cout<<len<<endl;
}
return 0;
}