LightOj 1045 Digits of Factorial
题意(好题)
给定一个数N,和进制k, 求N!在k进制下 位数的个数
思路
设进制为base,m为个数
N
!
=
b
a
s
e
m
N! = base^m
N!=basem,
m
m
m即 位数的个数
则
b
a
s
e
m
=
N
!
=
1
∗
2
∗
3
∗
4
∗
.
.
.
∗
(
n
−
1
)
∗
n
base^m = N! = 1 * 2 * 3 * 4 * ...* (n - 1) * n
basem=N!=1∗2∗3∗4∗...∗(n−1)∗n
两边同时取对数log
m
l
o
g
b
a
s
e
=
l
o
g
1
+
1
o
g
2
+
1
o
g
3
+
.
.
.
+
l
o
g
n
mlog^{base} = log1 + 1og2 + 1og3 + ..._+ logn
mlogbase=log1+1og2+1og3+...+logn
m
=
l
o
g
1
+
l
o
g
2
+
l
o
g
3
+
.
.
.
+
l
o
g
n
l
o
g
b
a
s
e
m = \frac{log1+log2+log3+...+logn}{log^{base}}
m=logbaselog1+log2+log3+...+logn
注意算的结果是下取整,则当结果m并不是恰好的数时,即存在小数的话,需要加
1
1
1
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1000010;
double s[N];
void init() {
s[0] = s[1] = 0;
for (int i = 2; i < N; i ++)
s[i] = s[i - 1] + log((double)i);
}
int main() {
init();
int T;
int id = 0;
scanf("%d", &T);
while(T --) {
int n, base;
scanf("%d%d", &n, &base);
if(!n) {
printf("Case %d: %d\n", ++id, 1);
continue;
}
double c = s[n];
double m1 = c / (log((double)base));
int m2 = c / (log((double)base));
if(m2 != (int)ceil(m1)) {
m2 ++;
}
printf("Case %d: %d\n", ++ id, m2);
}
return 0;
}