求n^n和n!的最左边的数字

原文出自:http://hi.baidu.com/matrush/item/aa83b1db96b131ff92a97427

[RQNOJ499]阶乘最高位

求n^n和n!的最左边的数,核心思想就是取10为底的对数推公式,n!还要用到斯特灵近似公式。

推广:求左边第x位只要推公式时将10^(k-1)变为10^(k-x)即可,最后答案取模10。

//n^n最左位
n^n的位数:k = [lg(n^n)] + 1 = [n * lg(n)]
最左边的数作个位:x = n^n / 10^(k-1)
取对数:lg(x) = n * lg(n) - (k-1) = (n*lg(n) - [n*lg(n)])
最左边的数:[x] = [10^lg(x)] = [10^(n*lg(n) - [n*lg(n)])]

//n!最左位
n!的位数:k = [lg(n!)] + 1
最左边的数作个位:x = n! / 10^(k-1)
取对数:lg(x) = lg(n!) - (k-1) = lg(n!) - [lg(n!)]
最左边的数:[x] = [10^lg(x)] = [10^(lg(n!) - [lg(n!)])]
n!将会很大,所以要用Stirling公式近似计算
Stirling公式:lim(n→∞) √(2πn) * (n/e)^n / n! = 1
也就是说当n趋于无穷大的时候,n!与√(2πn) * (n/e)^n的值十分接近
所以lg(n!) = lg(√(2πn) * (n/e)^n) = 1/2*(lg(2π) + lg(n)) + n * (lg(n) - lg(e))
代入[x] = [10^lg(x)] = [10^(lg(n!) - [lg(n!)])]即可。

提示:log10(d) = log(d)/log(10.0)

代码:

  1. #include <iostream>  
  2. #include <cmath>  
  3. using namespace std;  
  4. const double PI = acos(-1.0);  
  5. const double e = exp(1.0);  
  6. int main() {  
  7.     int n;  
  8.     while (scanf("%d", &n) != EOF && n) {  
  9.        //n^n  
  10.         double a = n * log10(n);  
  11.         printf("%d\n", (int)pow(10.0, a - (long long)a));  
  12.        //n!  
  13.         double b = (log10(2 * PI) + log10(n)) / 2 + n * (log10(n) - log10(e));  
  14.         printf("%d\n",(int)pow(10.0,b - (long long)b));  
  15.     }  
  16. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值