zoukankan      html  css  js  c++  java
  • soj 2666 分解 n!

    /*
    先说一个定理:
    若正整数n可分解为p1^a1*p1^a2*...*pk^ak
    其中pi为两两不同的素数,ai为对应指数
    n的约数个数为(1+a1)*(1+a2)*....*(1+ak)
    如180=2*2*3*3*5=2^2*3^2*5
    180的约数个数为(1+2)*(1+2)*(1+1)=18个。
    若求A/B的约数个数,A可分解为p1^a1*p2^a2*...*pk^ak,
    B可分解为q1^b1*q1^b2*...*qk^bk,则A/B的约数个数
    为(a1-b1+1)*(a2-b2+1)*(a3-b3+1)...*(ak-bk+1).
    然后说N的阶乘:
    例如:20!
    1.先求出20以内的素数,(2,3,5,7,11,13,17,19)
    2.再求各个素数的阶数
    e(2)=[20/2]+[20/4]+[20/8]+[20/16]=18;
    e(3)=[20/3]+[20/9]=8;
    e(5)=[20/5]=4;
    ...
    e(19)=[20/19]=1;
    所以
    20!=2^18*3^8*5^4*...*19^1
    解释:
    2、4、6、8、10、12、14、16、18、20能被2整除
    4、8、12、16、20能被4整除(即被2除一次后还能被2整除)
    8、16能被8整除(即被2除两次后还能被2整除)
    16能被16整除(即被2除三次后还能被2整除)
    这样就得到了2的阶。其它可以依次递推。
    所以在求N的阶乘质数因数个数时,从最小的质数开始,
    递归:
    int getNum(int n, int p) {
    if(n < p) return 0;
    else return n / p + getNum(n / p, p);
    }
    非递归:
    int getNum(int n, int m) {
    int res;
    res = 0;
    while (n) {
    res += n / m;
    n /= m;
    }
    return res;
    }

    其中P是质数,则该函数返回的就是N的阶乘中可以表达成质数P的指数的最大值。原理如上。
    */
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #define nmax 1000001
    int prime[nmax], pfactor[nmax], cpfactor[nmax];
    int plen, cplen;
    void mkprime() {
    int i, j;
    memset(prime, -1, sizeof(prime));
    for (i = 2; i < nmax; i++) {
    if (prime[i]) {
    for (j = i + i; j < nmax; j += i) {
    prime[j] = 0;
    }
    }
    }
    for (j = 2, plen = 0; j < nmax; j++) {
    if (prime[j]) {
    prime[plen++] = j;
    }
    }
    }
    int getNum(int n, int m) {
    int res;
    res = 0;
    while (n) {
    res += n / m;
    n /= m;
    }
    return res;
    }

    void solve(int n) {
    int i, cplen;
    for (i = 0, cplen = 0; (i < plen) && (prime[i] <= n); i++) {
    pfactor[cplen] = prime[i];
    cpfactor[cplen++] = getNum(n, prime[i]);
    }
    printf("%d=", n);
    printf("%d", pfactor[0]);
    if (cpfactor[0] > 1) {
    printf("^%d", cpfactor[0]);
    }
    for (i = 1; i < cplen; i++) {
    printf("*%d", pfactor[i]);
    if (cpfactor[i] > 1) {
    printf("^%d", cpfactor[i]);
    }
    }
    printf("\n");
    }
    int main() {
    #ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
    #endif
    int n;
    mkprime();
    while (~scanf("%d", &n) && n) {
    solve(n);
    }
    return 0;
    }

  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/xiaoxian1369/p/2208167.html
Copyright © 2011-2022 走看看