lightOJ 1220 Mysterious Bacteria

来源:互联网 发布:计算机专业学什么 知乎 编辑:程序博客网 时间:2024/05/16 00:40

题意:

给出一个数n,n是int范围,找出满足 n = x^b ,b的最大值。x为整数。

分析:

先打个素数表,再将n进行素因子分解,在对它的素因子的指数进行取最大公因数,例如 4500 = 2 ^ 2  * 3 ^ 2 * 5 ^ 4, 取gcd 后 =  2 ^ 2 * 3 ^ 2 * (5^2) ^ 2 = (2 *3 * (5^2) ) ^ 2;

故这个gcd就是结果。当n是负数时,因为一个数的偶数次方一定为正数,所以x一定为奇数,所以需要将它的素因子个数全部转换为奇数再处理。

代码:


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 1000010;bool vis[MAXN];long long prime[MAXN/10];int tot = 0;void getPrime()//求素数{    for(long long i = 2; i < MAXN; i++)        if(!vis[i])        {            prime[tot++] = i;            for(long long j = i*i; j < MAXN; j += i)                vis[j] = true;        }}int a[1000];//保存素因子int b[1000];//保存素因子的个数int cnt;void sbreak(long long n) //进行素因子分解{    memset(a, 0, sizeof(a));    memset(b, 0, sizeof(b));    cnt = 0;    for(int i = 0; prime[i]*prime[i] <= n; i++)    {        if(n%prime[i] == 0)        {            a[cnt] = prime[i];            while(n%prime[i] == 0)            {                b[cnt]++;                n /= prime[i];            }            cnt++;        }    }    if(n != 1)    {        a[cnt] = n;        b[cnt++] = 1;    }}int gcd(int a, int b){    return b?gcd(b,a%b):a;}int main(){    int T, ans, kase = 1, flag;    long long n;    getPrime();    scanf("%d", &T);    while(T--)    {        flag = 1;//标志,判断n是正数还是负数        scanf("%lld", &n);        if(n < 0) {n = -n, flag = 0;}        sbreak(n);        int t = b[0];        if(!flag) //如果n是奇数        {            if(t%2 == 0)            {                while(t%2 == 0) t /= 2;            }            for(int i = 0; i < cnt; i++) //将它的素因子的个数化为奇数            {                if(b[i]%2 == 0)                {                    while(b[i] %2 == 0) b[i] /= 2;                }                t = gcd(t,b[i]);            }        }        else for(int i = 0; i < cnt; i++)  t = gcd(t, b[i]);        printf("Case %d: %d\n", kase++, t);    }    return 0;}


原创粉丝点击