2018年全国多校算法寒假训练营练习比赛(第三场)A - 不凡的丈夫(Stirling)
Description:
夫夫有一天对一个数有多少位数感兴趣,但是他又不想跟凡夫俗子一样,
所以他想知道给一个整数n,求n!的在8进制下的位数是多少位。
Input:
第一行是一个整数t(0<t<=1000000)(表示t组数据)
接下来t行,每一行有一个整数n(0<=n<=10000000)
Output:
输出n!在8进制下的位数。
Sample Input:
3
4
2
5
Sample Output:
2
1
3
题目链接
这道题核心是运用斯特林公式。
斯特林公式(Stirling’s approximation)是
一条用来取n的阶乘的近似值的数学公式。一般来说,
当n很大的时候,n阶乘的计算量十分大,所以斯特林
公式十分好用,而且,即使在n很小的时候,斯特林
公式的取值已经十分准确。
——百度百科
ln(n!)=0.5ln(2npi)+nln(n)-n=0.5ln(2npi)+nln(n/e)
题目是要求出8进制下的位数,当用公式求出10进制下阶乘的位数后利用换底公式转化输出。
AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <set>
#include <map>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;
const double eps = 1e-5;
const double pi = asin(1.0) * 2;
const double e = 2.718281828459;
double Stirling_8(int n) {
return (log(2 * pi * n) / 2 + n * log(n / e)) / log(8) + 1;
}
int main() {
//ios::sync_with_stdio(0);
//cin.tie(0);
int t, n;
//cin >> t;
scanf("%d", &t);
while (t--) {
//cin >> n;
scanf("%d", &n);
double digit_8 = Stirling_8(n);
if (n < 2) {
digit_8 = 1;
}
//cout << (int)digit_8 << endl;
printf("%d\n", (int)digit_8 );
}
return 0;
}
不知道为什么这道题用cin、cout过不了,改为scanf、printf就可以过。