杭电ACM1018BigNumber解析
最后更新于:2022-04-01 09:48:30
~~~
# Big Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 31542 Accepted Submission(s): 14684
~~~
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
一开始看见这道题目不是很明白到底是什么意思,搞了好久才明白是:给一个数规定输入数字的个数,案例中给出了2也就是输入2个数,输入的这两个数求它的阶乘的位数,一开始想着是这样做:直接求指出然后求长度,这是最不需要动脑子的方法,但是,这个方法并不奏效,因为阶乘的数值是很大的,普通的int,long类型一旦求比较大的数的阶乘的时候往往会溢出,所以最好的方法应该是避免求他的值才行。
斯特林公式就可以用于求这个阶乘的位数,斯特林公式(Stirling's approximation)是一条用来取n的阶乘的近似值的数学公式。一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特林公式十分好用,而且,即使在n很小的时候,斯特林公式的取值已经十分准确。
上式两边同时取log10,得到的是log10(n!) = log10(2*pi*n)/2+n*log10(n/e)所以其位数应该可以表示为: log10(2*pi*n)/2+n*log10(n/e)+1
~~~
~~~~
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int[] nums = new int[num];
int num_digit = 0;
double d = 1;
int i = 0;
while(i < num)
{
num_digit = scanner.nextInt();
if(num_digit >= 2)
{
d = Math.log10(2 * Math.PI * num_digit) / 2 + num_digit * Math.log10(num_digit / Math.E) + 1;
}
nums[i] = (int)d;
i++;
}
//System.out.println("=====");
for(i = 0 ; i < num; i++)
{
System.out.println(nums[i]);
}
}
}
~~~
另外其他的方法还有
位数= log10(1) + log10(2) + log10(3) + ...... + log10(n) 取整数部分后+1