自测-2 素数对猜想
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
分析
这个问题一度令我很头疼,我试着按贺老师说的机械化思维去走,但是流程将自己弄糊涂了。于是跳出具体的问题,宏观的来看,有时会发现不一样的东西,发现这道题的核心其实是判断一个数是否为素数。这样的话就可以将这一功能单拎出来写成一个函数,然后在自己的程序里复用就可以了。
核心流程
每找到一个素数就加2看看是不是素数,如果是就计数,不是就继续找
其中每字就是循环的意思;是不是素数就是在使用判断素数的函数。
#include<stdio.h>
#include<math.h>
// 函数声明,这是一个判断是否为素数的函数
int tellPrimeNumber(int m);
int main()
{
int i,j=0;//声明主函数的循环变量和统计素数对的变量
int num,returnValue;//声明N和scanf的返回值
returnValue = scanf("%d",&num);//读入N的值
//对scanf的返回值进行处理
if(returnValue==1){
//从3开始,每次加2,判断是否是素数,因为比3大的偶数都不是素数
for(i=3;i<num;i=i+2){
if(tellPrimeNumber(i)==1){
if(tellPrimeNumber(i+2)==1){
j=j+1;//一个数和比他大2的数都是素数就记为一对,但并未改变i的值
}
}
}
printf("%d",j);
}else{
printf("输入错误");
}
return 0;
}
/*判断一个数是否是素数的函数*/
int tellPrimeNumber(int m)
{
/* 局部变量声明 */
int k; /*定义函数内部的循环变量*/
int n; // m 的平方根
n=(int)sqrt( (double)m );
/*从2开始,看他能否被比他小的数整除,如果能就不是素数*/
for(k=2;k<=n;k++){
/*判断输入的数是否能被除1和本身以外的数整除*/
if(m%k==0){
break;
}
}
/*只有是素数才会执行到k=n+1才跳出*/
if(k>n){
return 1; /*是素数就返回1*/
}else{
return 0; /*不是素数就返回0*/
}
}
但是遇到了问题,5个测试点过了4个,提示最后的那个是超时,我才意思到可能是执行效率太低了,但本程序的核心并不在大框架上,仍然在判断是否为素数那个函数上,要想办法提高函数的效率,后来发现判断一个数m是不是素数不需要从2到m-1挨个除,只需要除到根号m就可以,于是参考网上的除到根号m的算法,一改果然好使!