zzulioj 2560: 阶乘的位数
时间限制: 1 Sec 内存限制: 128 MB
提交: 450 解决: 101
[状态] [讨论版] [提交] [命题人:541723030106]
题目描述
一个数字通过阶乘,可以得到很大的数字。这里不需要算出阶乘后的数字,只需要的得到阶乘后数字的位数。 是不是有点太简单? 这里添加一点复杂的逻辑,请你算出N的阶乘,在B进制下的位数。
输入
第一行为整数T,代表有T组测试数据。
每组测试数据两个整数N和B。
数据范围: 0 < T <= 100, 0 <= N <= 1e5, 2 <= B < 16。(给出的N和B都是10进制数)
输出
输出N的阶乘,在B进制下的位数。
样例输入 Copy
1
4 2
样例输出 Copy
5
做题思路:
n!的位数为log10(n!)+1=log10(1)+log10(2)+log10(3)+…+log10(n)+1;
n!在B进制下的位数为logB(n!)+1=logB(1)+logB(2)+logB(3)+…+logB(n)+1;
***利用换底公式就可以求logB(n!)
即logB(n!)=(log10(1)+log10(2)+log10(3)+…+log10(n))/log10(B);**
#include <iostream>
#include<algorithm>
using namespace std;
int main()
{
int T, B, i, n;
double a, b;
cin >> T;
while (T--)
{
a = 0;
cin >> n >> B;
for (int i = 1; i <= n; i++)
{
a += log10(i);//求log10(1)+log10(2)+log10(3)+...+log10(n);(a要定义成浮点型)
}
b = a / log10(B);//求logB(n!);
cout << (int)b + 1<<endl;
}
return 0;
}
另一种方法:
利用斯特林公式(Stirling’s approximation);
斯特林公式(Stirling’s approximation)是一条用来取n的阶乘的近似值的数学公式。(详情问度娘)
利用此公式对上述公式进行优化
#include <iostream>
#include<algorithm>
using namespace std;
int main()
{
int T, B, n;
double a, b;
cin >> T;
while (T--)
{
a = 0;
cin >> n >> B;
a = log10(sqrt(2 * 3.14159265 * n)) + n * (log10(n)-log10(2.71828182));
b = a / log10(B);
cout << (int)b + 1<<endl;
}
return 0;
}