kuangbin带你飞数论

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;
}
上一篇:【转】vue中动态设置meta标签和title标签


下一篇:Sequel Pro for Mac(MySQL 数据库管理工具)破解版安装