LightOJ - 1220 Mysterious Bacteria(唯一分解定理+思维)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16554583/article/details/84257757

原题链接:传送门

题意:输入 t 组数n,每个数n = bp,求 p 的最大值。

思路:一开始以为是求 n = b1p1 * b2p2 * b3p3 * … *bnpn 中的最大的p,后来才注意到是 n = bp 中 p 的最大值…
可以先用唯一分解定理求出b1,b2,b3…bn,然后求出b1到bn的gcd,就是n = bp了。举两个例子12 = 22 * 3,gcd(2,1) = 1,那么12 = 121;144 = 24 * 3 2,gcd(4,2) = 2,那么144 = 122
而且这道题还有个坑点,n为负数时,p必定为奇数(p为偶数时,不论b的正负,n一定是个正数),所以n是负数且p为偶数时,p要一直除2,直到p为奇数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+1;
int book[N],prime[N];
int cnt = 0;

void GetPrime(){        //素数打表
    memset(book,0,sizeof(book));
    for(int i=2;i<N;i++){
        if(!book[i])
            prime[cnt++] = i;
        for(int j=0;j<cnt;j++){
            if(i * prime[j] > N)
                break;
            book[i*prime[j]] = 1;
            if(i % prime[j] == 0)
                break;
        }
    }
}

int main(){
    int t,Case = 1;
    int sum,ans;
    ll n;
    scanf("%d",&t);
    GetPrime();
    while(t--){
        scanf("%lld",&n);
        ans = 0;
        int flag = 0;
        if(n < 0){          //n为负数时
            n = -n;
            flag = 1;
        }

        for(int i = 0;i<cnt && prime[i]*prime[i] <= n;i++){
            sum = 0;
            while(n % prime[i] == 0){       //唯一分解定理
                n /= prime[i];
                sum ++;
            }

            if(ans == 0)
                ans = sum;
            else ans = __gcd(ans,sum);      
        }

        if(n != 1)
            ans = 1;
        if(flag){       //n为负数时
            if(ans % 2 == 0)    //ans必须是奇数
                while(ans % 2 == 0)
                    ans /= 2;
        }

        printf("Case %d: %d\n",Case++,ans);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_16554583/article/details/84257757