NYOJ-520 最大素因子
这个题基本上就两个知识点, 一个素数筛选法求素数,另一个是求最大公因子, 不过确定最大素数在素数表中的位置时,要用到二分的思想,不然会超时,下面是具体代码的实现;
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define SIZE 1000020 4 int prime[SIZE];//来保存素数,从下标1开始保存第一个 5 int temp[SIZE];//这个是用素数筛选法求出的素数 6 int maxPrimeFactor(int n)//求最大素因子的函数 7 { 8 int ans; 9 for(int i = 2; i * i <= n; i ++) 10 { 11 while(n % i == 0) 12 { 13 ans = i;//如果能求余, 那么当前的i 就是一个素因子 14 n /= i;//将n缩小 15 } 16 } 17 if(n > 1)//此时说明n 没有被任何一个素数整除, 最大素因子的当然是他本身 18 ans = n; 19 return ans; 20 } 21 int main() 22 { 23 // freopen("1.txt", "r", stdin);//利用重定向 24 // freopen("2.txt", "w", stdout); 25 int N; 26 temp[1] = 1; 27 for(int i = 0; i < SIZE; i ++)//将整个素数表初始化 28 temp[i] = i; 29 for(int i = 2; i * i< SIZE; i ++) 30 { 31 if(temp[i] != -1) 32 { 33 for(int j = i * i; j < SIZE; j += i) 34 temp[j] = -1;//如果不是素数就将它标记为-1 35 } 36 } 37 int index = 1; 38 for(int i = 2; i < SIZE; i ++) 39 { 40 if(temp[i] != -1) 41 prime[index ++] = temp[i];//将素数表中的素数复制到prime数组中 42 } 43 while(scanf("%d", &N) != EOF) 44 { 45 if(N == 1)//特殊数字,特别对待 46 { 47 printf("0\n"); 48 continue; 49 } 50 int left = 1, right = index - 1, mid = (left + right) / 2;//利用二分法确定最大素数在素数表prime中位置,如果直接for循环会超时 51 int maxPrime = maxPrimeFactor(N); 52 if(maxPrime == prime[right])//此时下标不是从零开始, 所以只有两个元素时,假如要确定后一个的位置,当前这个二分不行,这个特殊情况单独写出来 53 { 54 printf("%d\n", right); 55 continue; 56 } 57 while(maxPrime != prime[mid]) 58 { 59 if(maxPrime > prime[mid]) 60 left = mid; 61 else 62 right = mid; 63 mid = (left + right) / 2; 64 } 65 printf("%d\n", mid);//打印下标 66 } 67 return 0; 68 }