P 1007 素数对猜想
转跳点:🐏
日常水题,虽然要期中考试了,但提还是要水的,一共95题,早晚能水完。来来来,看题!
到目前为止,我发现乙题普遍需求明确。思路也很明确。这道题两种方法。
第一种:动态查找,从最大或最小的开始查找,并且从第二个素数出现开始,依次与上一个进行比较,从而确定素数对的个数。
第二种:先算出0~n范围内的所有素数,然后再查找素数对。
第一种需要快速的检验素数的算法;第二种需要快速的素数表算法
关于验证素数我专门写了一篇博客转跳点击我——>o(*////▽////*)q
思路大概就这样,下面看一下代码:
第一种:
/** * @brief 动态计算素数对 * @note 关键点都注释了 * @author 杨文蓁的小迷弟 */ #include <stdio.h> #include <math.h> #define MAX 100000 int main() { int n, count = 0; scanf("%d", &n); int prePrime = 0; // 存放上一个素数 for (int i = n; i > 1; i--) { int flag = 1; for (int j = 2; j <= (int)sqrt(i); j++) { if (i % j == 0) { flag = 0; // 标记位为0表示当前i不为素数 break; } } if (flag == 1) // 标记位为1表示当前i为素数 { if (prePrime > 1 && prePrime - i == 2) // 判断相邻两素数之差 { count++; } prePrime = i; } } printf("%d\n", count); return 0; }
第一种比较简单,直接贴了
第二种:
1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 100010 4 5 /** 6 * @brief Euler筛法 7 * @note 线性打表 8 * @param size: 范围 9 * @author 杨文蓁的小迷弟 10 */ 11 int Isprime[MAXN]; 12 int Prime[MAXN]; //记录素数 13 14 void Euler_prime(int size); 15 16 int main() 17 { 18 int size, cnt = 0; 19 scanf("%d", &size); 20 Euler_prime(size); 21 for (int i = 0; i < size; i++) 22 { 23 if (2 == Prime[i + 1] - Prime[i]) 24 { 25 //printf("Prime[%d] - Prime[%d]\n%d - %d = %d\n", i+1, i, Prime[i+1], Prime[i], Prime[i+1] - Prime[i]); 26 cnt++; 27 } 28 } 29 printf("%d\n", cnt); 30 return 0; 31 } 32 33 void Euler_prime(int size) 34 { 35 int cnt = 0; //记录素数个数 36 37 Isprime[0] = Isprime[1] = 1; 38 for (int i = 2; i <= size; i++) 39 { 40 if (!Isprime[i]) // 41 { 42 Prime[cnt++] = i; 43 } 44 for (int j = 0; j < cnt && i * Prime[j] < size; j++) //在MAXN范围内讲所有已得出的素数的倍数都清除 45 { 46 Isprime[i * Prime[j]] = 1; 47 if (!(i % Prime[j])) //如果被1某个素数整除的话那就意味着被其他素数筛过了,往后就不用继续了 48 { 49 break; 50 } 51 } 52 } 53 }
建议试一下第二种,方法当作锻炼。
PAT不易,诸君共勉!
大道五十,天衍四九,人遁其一!