HDOJ 1018 Big Number
题目
点此查看 HDOJ 1018 Big Number
题意
求 n! 是几位数
分类
数论 公式化简
题解
N最大为 10^7 直接按大树求 N! 时间复杂度是难以忍受的
故要化简 设 N! 的位数 为 m
m = log10(N!)
继续化简 (我没想到,看其他人的代码)
由 斯特林公式![]()
log10(n!)= log10(√(2πn))+nlog10(n/e) (点击查看百度百科 斯特林公式)
技巧
出于新手,我自己是没想到斯特林公式的
我是 log10(N!)
打表解的
由于 n 最带为 10 ^ 7 第一次超时了
然后我就改成每 10 个打一次表,然后根据值找到 它的值再计算(比如 1234 找到 1230 再 计算)
虽然方法效率低,也复杂,不过算是一种打表的启发吧
代码 (斯特林公式法)
由于 有写好的,就不重复劳动了
斯特林公式法解题
代码 (log10(N!) 打表)
#include <iostream>
#include <cmath>
#define max 1000010
using namespace std;
double b[max + 1];
int main()
{
int n,m,g,s,z = 0,f;
double t = 0;
cin >> n;
b[z++] = 0;
for(int i = 1;i <= 10;i++)
t += log10(i);
b[z++] = t;
for(int i = 11;i < max * 10;i += 10)
{
t = 0;
for(int j = i;j < i + 10;j++)
t += log10(j);
b[z] = b[z - 1] + t;
z++;
}
while(n--)
{
// for(int i = 0;i < 10;i++)
// cout << b[i] << endl;
cin >> m;
cout << (int)(b[m/10]) + 1 << endl;
t = 0;
f = (m/10) * 10 == 0 ? 1 : (m/10) * 10;
if(!(m/10))
for(int i = f;i <= m;i++)
t += log10(i);
else
for(int i = f;i < m;i++)
t += log10(i);
cout << (int)(b[m/10] + t) + 1 << endl;
}
return 0;
}