题目:
链接: https://acm.dingbacode.com/showproblem.php?pid=1018
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
题目大意:
大概意思就是,在很多时候,我们需要用到位数很大的数字 ,但在这题中,我们将会被给到一个数字m(1 ≤ m ≤ 10^7),我们需要做的是输出 这个数字m)的阶乘)的位数)。
例如:
10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3 628 800 (7位数,那么我们输出 “7” )
对于标准输入,值得一提的是,输入的第一行为 n,表示有 n 种情况需要我们考虑,接下来有连续 n 行的输入。
对于标准输出,很简单,一个case一行。所以这题几乎不用考虑格式。
题目解析:
很多小伙伴在拿到这题时,肯定嘴角一笑 : ) 哈哈,这不是随便用循环或者递归求个阶乘的小case吗?虽然这题是个水题,但也不是这么水的,人毕竟是个2002年亚洲水题 : (
题目中给出的整数范围是1到一千万,如果让你求一千万的阶乘,可能会Time Limit Exceeded Of Your Life. 这时,如果我们引入一个数学式子“log”,会发现好像和这道题很适配,log10可以巧妙的求出数字的位数,例如:
log10(99) = 1.995635; 两位数
log10(100) = 2 ; 三位数
log10(999) = 2.9995654; 三位数
//总结规律,数字的位数等于求得结果的 整数位+1
更巧的是,log函数十分适合于阶乘:
log10(10!) = log10(10*9*8*7*6*5*4*3*2*1) = log10(10)+log10(9)+log10(8)+....+log10(1)
这时问题已经简化了很多。我们不必求出数字 m 的阶乘结果,它的结果十分容易溢出 int 型,而且求阶乘的过程对于计算机来说也有些痛苦。
代码思路:
我们的代码目前需要解决2个问题:
1 ) 如何从 log10(m!) 的结果中,剥离出整数部分;
2 ) log 函数怎样使用;
解决方法很简单:
1 ) 我们可以在输出结果时,使用 int (向下取整)强制转换数据类型;
2 ) http://www.cplusplus.com/reference/cmath/log/ #c++官网教程中我们可以看到
log函数的使用方法是 double log (double x); 并且包含在<cmath>头文件中。
附AC代码:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main()
{
int n, m, i;
cin >> n;
/* n 个情况需要解决*/
while (n--)
{
/*log函数的返回值为double型*/
double sum = 0;
cin >> m;
for (i = 1; i <= m; i++)
sum += log10((double)i);
/*涉及强制转换使用printf较为合适*/
printf("%d\n", (int)sum + 1);
}
return 0;
}
水题不太水,且做且珍惜 ...
zjsru_cs202 fanyuchen