问题
My solution was pretty fast but not enough. I need more faster. How can I reduce my time? Input Number: n (0 ≤ n ≤ 1000000) Base should be: base (2 ≤ base ≤ 1000)
- Input 5! in 10 base. Output is: 3
- Input 22! in 3 base. Output is: 45
Time Limit: 2 second(s), and Memory Limit: 32 MB
Here is my code in c language:
#include<stdio.h>
#include<math.h>
int factorialDigitExtended ( int n, int base ) {
double x = 0;
for ( int i = 1; i <= n; i++ ) {
x += log10 ( i ) / log10(base);
}
int res = ( (int) x ) + 1;
return res;
}
int main(){
int i, t, n, b;
for(i=1; i<= t; i++){
scanf("%d %d", &n, &b);
printf("Case %d: %d\n", i, factorialDigitExtended(n, b));
}
return 0;
}
回答1:
Like I mentioned in the comment above this might be target specific behavior. A few things I would look at:
Only calculate constant values once:
int factorialDigitExtended ( int n, int base ) {
double x = 0;
double lbase = log10(base);
for ( int i = 1; i <= n; i++ ) {
x += log10 ( i ) / lbase;
}
int res = ( (int) x ) + 1;
return res;
}
Division may be expensive:
int factorialDigitExtended ( int n, int base ) {
double x = 0;
double lbase = 1 / log10(base);
for ( int i = 1; i <= n; i++ ) {
x += log10 ( i ) * lbase;
}
int res = ( (int) x ) + 1;
return res;
}
Don't repeat the same multiplication n times:
int factorialDigitExtended ( int n, int base ) {
double x = 0;
double lbase = 1 / log10(base);
for ( int i = 1; i <= n; i++ ) {
x += log10 ( i );
}
x *= lbase;
int res = ( (int) x ) + 1;
return res;
}
0 compare might be cheaper:
int factorialDigitExtended ( int n, int base ) {
double x = 0;
double lbase = 1 / log10(base);
for ( int i = n; i > 0; --i ) {
x += log10 ( i );
}
x *= lbase;
int res = ( (int) x ) + 1;
return res;
}
Btw (int) x might fail at some points due to precision problems.
There might also be processor specific logarithm instructions.
来源:https://stackoverflow.com/questions/40909278/find-the-number-of-digits-of-the-factorial-of-an-integer-in-a-certain-base