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;    
}
posted @ 2012-07-14 22:04  沐阳  阅读(393)  评论(0编辑  收藏  举报