题目挺有意思。
计算n(<1e7)!的位数,一般我们会想如果知道这个数具体是多少就好办了。
然而n太大根本无法计算,其实把具体数值算出来对于求解本题是充分但非必要的条件。
我一开始考虑用把数值都用科学计数法表示出来,考虑两个浮点数相乘得到新的浮点数,更新10的幂就可以了。
然后实验过程中发现当n较大时运算的时间效率和结果的准确性均无法保证。
合理的解法是这样的。
我们假设n! = 10M, M为实数,那么显然n!的位数就等于M向下取整加一的值。
那么M = log(n!) = ∑log(i) (i ≤ n) (log指以10为底的对数)。
直观上我们可以这样理解,我们知道数值1000的位数为4这是因为log(1000) + 1 = 4,数值1001的位数为4因为(int)log(1001) + 1 = 4。
这里位数作为整数代表了原数字一部分性质。
我们推广位数到实数,使其具备原数的所有性质,即 log(i)。
那么由于对数的运算性质,数的相乘就变成了位数的相加。
结果即为所求。
http://acm.hdu.edu.cn/showproblem.php?pid=1018
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 5 using namespace std; 6 7 int n; 8 9 void solve(){ 10 double M = 0; 11 for(int i = 1; i <= n; i++) M += log10(i); 12 int ans = (int)M; 13 printf("%d ", ans + 1); 14 } 15 16 int main(){ 17 int T; 18 scanf("%d", &T); 19 while(T--){ 20 scanf("%d", &n); 21 solve(); 22 } 23 return 0; 24 }