(int)log10((int)n)+1 计算位数的几个问题

论坛 期权论坛 脚本     
匿名技术用户   2020-12-28 10:51   11   0

Big Number

Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2768 Accepted Submission(s): 1276


Problem Description
In many applications very large integers numbers are required. Some of these applications are using keys for secure transmission of data, encryption, etc. In this problem you are given a number, you have to determine the number of digits in the factorial of the number.

Input
Input consists of several lines of integer numbers. The first line contains an integer n, which is the number of cases to be tested, followed by n lines, one integer 1 ≤ n ≤ 107 on each line.

Output
The output contains the number of digits in the factorial of the integers appearing in the input.

Sample Input
2
10
20

Sample Output
7
19

题目的大意是说给定一个数并且这个数有可能很大,求这个数阶乘后的位数。
log10(n!)=log10(1*2*3…*n)=log10(1)+log10(2)+…+log10(n),这个公式当时看的时候想不明白,为什么取以10为底的对数就是这个数的位数,其实看log10(10)就明白了,这个数值是1,而位数正好就增加1。对log10(n!)的值取整加1就是n!的位数。n这个数如果不大的话这样做,10^7的话这样做肯定超时的。需用斯特林公式:
log10(n!) = log10(sqrt(2 * pi * n)) + n * log10(n / e)
当n>3的时候这个公式成立。当n<=3的时候位数为1。
在杭电上提交用第一个公式就能ac,代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int digit(int number)
{
int i;
double sum=0;
for(i=1;i<=number;i++)
sum+=log10(double(i));//根据公式得来的
sum=floor(sum)+1;//向下取整函数
return sum;
}
int main()
{
int num;
cin>>num;
while(num--)
{
int dig;
cin>>dig;
cout<<(int)digit(dig)<<endl;
}

return 0;
}
但是在北大上就TLE错误,只好用斯特林公式去做,ac。
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int digit(int number)
{
double PI=acos(double(-1));//获取PI的值,原来还不知道有这个公式,对-1取反余弦函数。
double e=exp(double(1));//获取自然底数e的值
return int(log10(sqrt(2*PI*number))+number*log10(number/e))+1;
}
int main()
{
int num;
cin>>num;
while(num--)
{
int dig;
cin>>dig;
cout<<(int)digit(dig)<<endl;
}
return 0;
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP