UVA11466 Largest Prime Divisor

问题链接:UVA11466 Largest Prime Divisor

这个问题由于输入的n比较大,最大达到10^15,所以处理起来有些繁琐。

由于sqrt(10^15)=31622776,所以首先求出小于31622776的素数备用。这个范围的素数有1951957个。这些数值需要事先计算,以便于定义数组时,既不会不够用也不会浪费空间。

对于输入的n,从小到大用素数去除n(欧拉函数原理),直到得到最大因子。

AC通过的C++语言程序如下:

/* UVA11466 Largest Prime Divisor */

#include <iostream>
#include <cmath>

using namespace std;

#define MAXN 31622776
bool sieveflag[MAXN+1] = {false, false, true};

#define PRIMEN 2000000
int prime[PRIMEN] = {2};
int count;

void esieve(bool sflag[], int n)
{
    // 初始化
    for(int i=3; i<=n; i++) {
        sflag[i++] = true;
        sflag[i] = false;
    }

    // 筛选
    int max = sqrt(n);
    for(int i=3; i<=max; i++){
        if(sflag[i]) {
            for(int j=i+i; j <= n; j+=i)
                sflag[j] = false;
        }
    }

}

void setprime(int prime[], bool sflag[], int n)
{
    int i;

    count = 1;

    for(i=3; i<=n; i++)
        if(sflag[i])
            prime[count++] = i;
}

int main(void)
{
    long long n, m;

    esieve(sieveflag, MAXN);

    setprime(prime, sieveflag, MAXN);

    while(cin >> n) {
        // 判定结束条件
        if(n == 0)
            break;

        // 负数的处理
        if(n < 0)
            n = -n;

        int factcount = 0;
        for(int i=0; i<count; i++) {
            if(n < prime[i])
                break;

            if(n % prime[i] == 0) {
                m = prime[i];
                factcount++;
                while (n % m == 0)
                    n /= m;
            }
        }
        if (n != 1) {
            m = n;
            factcount++;
        }

        if(factcount > 1)
            cout << m << endl;
        else
            cout << "-1" << endl;
    }

    return 0;
}




原文地址:https://www.cnblogs.com/tigerisland/p/7564551.html