斯特林公式
定义:
斯特林公式是用来求N的阶乘近似值的公式:
公式为:
n ! = 2 π n ( n e ) n n!=\sqrt{2\pi n}(\frac{n}{e})^n n!=2πn(en)n
公式的应用:求n!的位数
大家都知道,求一个十进制数n的位数,可以对10取对数然后加一,即:
l o g 10 ( n ) + 1 log10(n)+1 log10(n)+1
假设ans代表n!的位数,则
a n s = l o g 10 ( n ! ) + 1 = l o g 10 ( 2 π n ( n e ) n ) + 1 = l o g 10 ( 2 π n ) + l o g 10 ( n e ) n + 1 − − − ( 1 ) ans=log10(n!)+1=log10(\sqrt{2\pi n}(\frac{n}{e})^n)+1=log10(\sqrt{2\pi n})+log10(\frac{n}{e})^n+1---(1) ans=log10(n!)+1=log10(2πn(en)n)+1=log10(2πn)+log10(en)n+1−−−(1)
或者:
a n s = l o g 10 ( n ! ) + 1 = l o g 10 ( 1 ) + l o g 10 ( 2 ) + . . . . . . + l o g 10 ( n − 1 ) + l o g 10 ( n ) + 1 − − − ( 2 ) ans=log10(n!)+1=log10(1)+log10(2)+......+log10(n-1)+log10(n)+1---(2) ans=log10(n!)+1=log10(1)+log10(2)+......+log10(n−1)+log10(n)+1−−−(2)
案例:
1.求N!的位数:
解题:直接运用斯特林公式(2)
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
using namespace std;
int main(){
int m;cin>>m;double sum=0;for(int i=1;i<=m;i++){sum+=(double)log10(i);//以浮点数加 //c++支持log2(),ln()即log(),log10() }sum+=1;cout<<(int)sum<<endl;//sum向下取整 return 0;
}
2. N!的位数(n更大,n<=10^9)
解题:直接运用斯特林公式(1)
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
using namespace std;
double pi=acos(-1.0);
double e=exp(1.0);
int main() {int t;cin>>t;while(t--) {ll n;cin>>n;ll len=log10(sqrt(2*pi*n))+n*log10(n/e)+1;cout<<len<<endl;}
}
3.求N的阶乘的准确值
解题:由于n最大到10000,即使用long long也无法表示,所以计算结果需要保存在数组中。
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
using namespace std;
int main() {int ans[50000],n;//ans数组用于存储结果 int cnt=1,carry=0,res;//cnt表示计算结果位数,carry表示进位,res中间变量 while(cin>>n) {for(int i=0; i<50000; i++)ans[i]=0;//初始化赋0 ans[0]=1;for(int i=2; i<=n; i++) {for(int j=0; j<cnt; j++) {res=ans[j]*i+carry;//i与ans数组的每一位相乘 ans[j]=res%10;//存储个位数字 carry=res/10;}while(carry>0) {//处理最高位的进位 ans[cnt++]=carry%10;carry/=10;}}for(int i=cnt-1; i>=0; i--)cout<<ans[i];//从高到低位输出 cout<<endl;}return 0;
}
4.N的阶乘同余P
解题:每做一次乘法,将结果mod P
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
using namespace std;
int main(){
ll N,P;
cin>>N>>P;
ll ans=1;
for(int i=1;i<=N;i++){
ans=ans*i%P;
}
cout<<ans<<endl;
return 0;
}
说明:在c++中 pi=acos(-1.0),因为 cos(pi)=-1.0,利用反三角函数,自然对数e=exp(1.0)