问题链接: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; }