中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题

自测-2 素数对猜想
让我们定义d​n​​为:d​n​​=p​n+1​​−p​n​​,其中p​i​​是第i个素数。显然有d​1​​=1,且对于n>1有d​n​​是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<10​5​​),请计算不超过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的算法,一改果然好使!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值