1007 素数对猜想

1007 素数对猜想 (20 分)

题目描述:

让我们定义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的两个素数。由于除了2之外的所有素数都是奇数,所以求 <= N 的所有素数对的个数就是求 <= N 的奇数序列中有几个相邻的素数对。
本题的另一个考点就是如何判断一个数是否为素数。 判断一个数是否是素数有多种方法,最常见的就是按照素数的定义(只能被 1 和 其自身 整除)。


代码:

def main():
    n = int(input())
    # 接收输入的整数
    answer = 0
    temp = 3
    # 奇素数序列的首个元素
    front = True
    end = False
    # front 和 end  非别表示两个相邻的奇数是否是素数,
    # 当 front == True and end == True 的时候就找到了一个素数对。
    while temp + 2 <= n:
        temp += 2
        # 每次循环 temp + 2,变为下一个奇数
        if isPrime(temp):
            #如果这个奇数是素数, end = True
            #注意循环从5开始,前一个奇数是3,所以front的初始值设置为True
            end = True
        if front and end:
            #front == True and end == True 的时候就找到了一个素数对
            answer += 1
        front = end
        end = False
        # 在下一次循环之前,将front的值改为刚刚判断过的,把end的值设置为False 

    print(answer)


def isPrime(x):
    #  判断x是否是素数
    if x == 2 or x == 3 or x == 5 or x == 7:
        # < 9 的奇数直接判断
        return True
    if x <= 1 or x % 2 == 0:
        # 非正整数或者偶数都不是奇数
        return False
    boundary = int(x ** 0.5) + 1
    # 素数判断的边界是 根号x , 稍微放大一点便于处理边界值。如 x == 9时,为了使
    # 循环的条件能够满足,需要boundary 稍大一点。
    """
    x ** 0.5 就是对 x 开根号,**表示幂运算。
    为什么判断到 根号x 就行了呢? 举个例子,3 < 15 ** 0.5 < 4, 我们只需要
    判断到 4(实际上到3即可,为了偷懒起见,我们可以稍微放大一点判断的范围)。
    因为 15 == 3 * 5 , 既然 15 能被3整除那它就不是素数,而15能否被5整除的
    判断是不必要的。
    """
    #循环判断从 9 开始的各个奇数是否能被除了 1 和 它自身之外的奇数整除。
    for y in range(3, boundary + 1, 2):
        if x % y == 0:
            # 如果能被整除,不是素数
            return False
    # 不能被别的数整除,是素数
    return True

if __name__ == '__main__':
    main()

  • C++ Version:
#include <iostream>
#include <math.h>
using namespace std;

bool isPrime(int );
int main(){
	//freopen("in.txt", "r", stdin);
	int N;
	cin >> N;
	int answer = 0, tmp = 3;
	bool pre = false, now = false;
	while (tmp <= N){
		if (isPrime(tmp)){
			now = true;
		}else{
			now = false;
		}
		if(pre && now){
			answer += 1;
		}
		pre = now;
		tmp += 2;
	} 
	cout << answer << endl;
	return 0;
} 

bool isPrime(int x){
	if(x <= 1 || x % 2 == 0){
		return false;
	}
	if(x == 3 || x == 5 || x== 7 ){
		return true;
	}
	int bound = int(sqrt(x) + 1);
	for(int i=3; i<=bound; i+=2){
		if(x % i == 0){
			return false;
		}
	}
	return true;
}
  • Java Version:
import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		in.close();
		// 接收输入的正整数
		boolean pre = false;
		boolean	now = false;
		int answer = 0;
		// 记录一共有多少素数对
		int tmp = 3;
		while(tmp <= N) {
			// 更新当前数字是否为素数的标记
			if(isPrime(tmp)) {
				now = true;
			}else {
				now = false;
			}
			if(now && pre) {
				// 找到一个素数对
				answer += 1;
				//System.out.println(tmp-2 + " " + tmp);
			}
			// 更新前一个数是否是素数的标记
			pre = now;
			tmp += 2;
		}
		System.out.print(answer);
	}
	public static boolean isPrime(int x) {
		// 判断输入的正整数是否是素数,只能被1和自身整除的数是素数。
		if(x == 2 || x == 3 || x == 5 || x == 7) {
			return true;
		}else if(x <=1 || x % 2 == 0) {
			return false;
		}else {
			for(int i=3; i<=(int)(Math.sqrt(x)); ++ i) {
				if(x % i == 0) {
					return false;
				}
			}
		}
		return true;
	}
}

易错点:

  • 正确写出判断素数的算法
  • 在判断素数对的时候要尽量减少重复计算避免超时

总结:

  • 判断一个数是否是素数是机试中十分常见的问题,所以请务必掌握。

xiaoshengshuo
以上程序都是通过全部测试点的,小声说。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值