POJ-1730 Perfect Pth Powers 分解质因子

该题题意就是求一个数最多能够开多少次方,这其中包含有负数,而且要用long long 型数据读入。首先将这个数的素因子分解求出,统计出它们的各自的个数,然后对它们的个数求一个gcd,最后输出。如果是正数的话直接输出,如果是负数的话需要将其的最大奇因子求出。

代码如下:

#include <cstdlib>

#include <cstring>

#include <cstdio>

#include <algorithm>

#include <cmath>

using namespace std;



int p[66000], cnt;



long long rec[6600], N; 



int son[6600];



int gcd(int a, int b)

{

    return b == 0 ? a : gcd(b, a % b);    

}



void pre()

{

    int k;

    for (int i = 4; i <= 66000; i += 2) {

        p[i] = 1;

    }

    for (int i = 3; i <= 257; i += 2) {

        if (!p[i]) {

            k = 2 * i;

            for (int j = i * i; j <= 66000; j += k) {

                p[j] = 1;

            }

        }

    }

    cnt = 1;

    rec[1] = 2;

    for (int i = 3; i <= 66000; i += 2) {

        if (!p[i]) {

            rec[++cnt] = i;

        }

    }

//    printf("cnt = %d\n", cnt);

}



int deal(long long x)

{

    bool flag = true;

    int ans = 0;

    for (int i = 1; i <= cnt; ++i) {

        while (x % rec[i] == 0) {     

            son[i]++;

            x /= rec[i];

        }

    }

    if (x != 1) {

        return 1;

    }

    for (int i = 1; i <= cnt; ++i) {

        if (son[i]) {

            ans = gcd(ans, son[i]);

        }

    }

    return ans;

}

// 1728 = 12 ^ 3  11664 = 108^2

int main()

{

    int ans;

    pre();

    while (scanf("%I64d", &N), N) {

        memset(son, 0, sizeof (son)); 

        ans = deal(N < 0 ? -N : N);

        if (N < 0) {

            while (!(ans & 1)) {

                ans >>= 1;

            }

            printf("%d\n", ans);

        }

        else {

            printf("%d\n", ans);

        }

    }

    return 0;    

}

你可能感兴趣的:(poj)