zoukankan      html  css  js  c++  java
  • 算法笔记刷题7(PAT乙级1007素数猜想)

    算法笔记刷题7(PAT乙级1007素数猜想)

    题目

    让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

    现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。

    输入格式:

    输入在一行给出正整数N

    输出格式:

    在一行中输出不超过N的满足猜想的素数对的个数。

    输入样例:

    20
    

    输出样例:

    4
    

    解答

    看到这个题我是不屑一顾的,因为“看起来”就是很简单啊!!!于是我飞快写出了第一个版本:

    1.0

    思路很简单:这种相差2的只可能是奇数啊,我从3开始把里面的奇数都抓来看看是不是素数不就行了?(是我太天真了呜呜呜)

    #include <stdio.h>
    int primeNum(int n);
    
    int main()
    {
        int n,count=0;
    	scanf("%d",&n);
    	if(n>4){
    		for(int i=3;i+2<=n;i=i+2){
    			int t;
    			t=primeNum(i)*primeNum(i+2);
    			if(t==0)count++;
    		}
    		
    	}
    	printf("%d",count);
    	return 0;
    }
    int primeNum(int n){
    	if(n==2)return 0;
    	for(int i=2;i<n;i++){
    		if(n%i==0)return 0;
    	}
    	return 0;
    }
    

    然后就到了大家喜闻乐见的丢人环节:

    image.png

    然后天真的我觉得要减少函数调用,眉头一皱计上心来,搞出了1.5个版本

    1.5

    #include <stdio.h>
    int primeNum(int n);
    
    int main()
    {
        int n,count=0;
    	scanf("%d",&n);
    	if(n>4){
    		for(int i=3;i+2<=n;i=i+2){
    			int t;
    			t=primeNum(i);
    			if(t==1)count++;
    		}
    		
    	}
    	printf("%d",count);
    	return 0;
    }
    int primeNum(int n){
    	int n1=n+2;
    	for(int i=2;i<n;i++){
    		if(n%i==0)return 0;
    	}
    	for(int i=2;i<n1;i++){
    		if(n1%i==0)return 0;
    	}
    	return 1;
    }
    

    然后,然后就又超时了呢呜呜呜?????

    开始查资料简化:首先,判断一个数n是不是素数,只需要判断从2到根号n的区间内有没有能整除它的。其次,我的素数判断做了很多的重复工作。比如判断3,5,7三个数字时,我已经算出了3,5均为素数,到计算5,7时候又得算一次5。即除了首尾外多做了一遍无用功。

    综合,我写出了2.0版本

    2.0

    如果能把从3开始的素数表打出来,再判断前后两个数字的间距是否为2,工作量会减少很多很多。

    #include<stdio.h>
    #include<math.h>
    int a[100000];
    int main()
    {
        int n,t=0,k=0;
        scanf("%d",&n);
        for(int i=3;i<=n;i=i+2){
        	int j;
            for(j=2;j<=sqrt(i);j++){
                if(i%j==0)
                    break;
            }
            if(j>sqrt(i))
                a[k++]=i;
        }
        for(int i=0;i<=n;i++){
            if(a[i+1]-a[i]==2){
                t++;
            }
        }
        printf("%d",t);
        return 0;
    }
    

    结果:

    image.png

    这个时间比较理想。因为如果不把素数表打出来,光改素数的判断方式的话,最后一个点用时是31ms。

  • 相关阅读:
    导入旧版本Android项目时的“Unable to resolve target ‘android
    eclipse打开文件目录
    ireport常见问题
    【技术贴】解决127.0.0.1和http://localhost均被拦截跳转到另一个网页
    【技术贴】SqlServer2008 R2 安装失败提示出现以下错误 服务 MSSQLSERVERO
    【技术贴】解决xp下Microsoft.SqlServer.Management.PSProvider.dll
    websphere性能设置和日常维护
    【技术贴】解决支付宝充值信用卡还款跳转到网上银行报错Error 404
    jQuery制作Facebook Timeline时间轴
    借助rownum中求Oracle表中前三名(三甲:状元榜眼探花)的方法(总计三种方法,以讲述rownum的使用为主)
  • 原文地址:https://www.cnblogs.com/yiyefuyou/p/12873310.html
Copyright © 2011-2022 走看看