SAC E#1 一道中档题 Factorial
思路:一个数x在y进制下末尾有多少零, 就是在十进制下能被y连续整除的次数
首先分解k进制,然后对于每个质因数,求出n!里有多少个质因数,然后如果k里有x个这个质因数,则求出的结果除以x。最后的答案为这些结果的最小值
如何求n!里有多少个k分解出来的质因数
代码QAQ
#include<cstdio> #include<iostream> #define ll long long using namespace std; const ll sz = 1e7, inf = 1e18; ll n, k, cnt = 0, num = 0, ans = inf; ll pri[sz], jz[sz], book[sz]; bool pd[sz]; void getlist() {//没问题 ll up = min(max(n, k), sz); pd[1] = pd[0] = 1; for(ll i = 2; i <= up; i++) { if(!pd[i]) pri[++cnt] = i; for(ll j = 1; j <= cnt && pri[j] * i <= up; j++) { pd[i * pri[j]] = 1; if(i % pri[j] == 0) break; } } } void resolvek(ll x) {//没问题 for(ll i = 1; i <= cnt; i++) { if(x == 1 || pri[i] > n) break; if(x % pri[i] == 0) { jz[++num] = pri[i]; while(x % pri[i] == 0) { //这里参考的题解!tql!!! x /= pri[i]; book[num]++; } } } } int main() { scanf("%lld%lld", &n, &k); getlist(); resolvek(k); for(ll i = 1; i <= num; i++) { ll t = n, sum = 0; while(t) { t /= jz[i]; sum += t; } ans = min(ans, (ll)sum/book[i]); } // if(ans == inf) printf("0"); printf("%lld", ans); return 0; }
inf 要定义的大一点 刚开始inf = 1<<30 ans 比inf要大, 这就十分gg了