Question:
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N
(<10次方5),请计算不超过N
的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N
。
输出格式:
在一行中输出不超过N
的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
1.思路分析:
本题是寻找输入范围内的相邻素数且数值相差为2的素数对的个数。输入为一个整数,输出为一个整数。
2.具体步骤:
需要找到输入数值中的素数并判断是否满足条件,因此需要作如下准备:
(1).判断一个数字是否为素数
(2).判断相邻素数的值是否相差为2
(3).从当前素数开始,寻找下一个素数
package PATC7;
import java.util.Scanner;
public class Main {
//判断两个数字的差值是否为2,若是,返回true
public static boolean is2(int a,int b)
{
if((b-a)==2)
{
return true;
}
else
{
return false;
}
}
//判断当前数字是否为素数,快速版本
public static boolean isPrime_v2(int n) {
if (n < 2) {
return false;
} else if (n == 2) {
return true;
} else {
int temp = (int) Math.sqrt(n);
for (int i = 2; i <= temp; i++) {
if (n%i == 0) {
return false;
}
}
return true;
}
}
//判断当前数字是否为素数,超时慢速版本
public static boolean isPrime(int num)
{
boolean isPrime=true;
for(int i=num/2;i>=2;i--)
{
if(num%i==0)
{
isPrime=false;
}
}
return isPrime;
}
//获取下一个素数的值,
public static int nextPrime(int prime)
{
for(int i=prime+1;;i++)
{
if(isPrime_v2(i))
{
return i;
}
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
//获取输入数字
int num=Integer.parseInt(sc.nextLine());
//初始化相邻的两个素数,答案
int prime_num1=2;
int prime_num2=0;
int answer=0;
//用来寻找第一个素数,规定从2开始
int init_value=2;
//初始化赋值第一个素数,第二个素数
prime_num1 = nextPrime(init_value);
prime_num2 = nextPrime(prime_num1);
//当获取的两个素数都在范围内时,
while((prime_num1<=num)&&(prime_num2<=num))
{
//判断两个素数的差值是否为2
//差值为2,answer+1;
if(is2(prime_num1,prime_num2))
{
//更新两个素数对为下一个素数
answer++;
prime_num1=prime_num2;
prime_num2=nextPrime(prime_num1);
}
//差值不为2
else
{
//更新两个素数对为下一个素数
prime_num1=prime_num2;
prime_num2=nextPrime(prime_num1);
}
}
//输出
System.out.println(answer);
}
}
补充:判断是否为素数的方法在这个问题中采用一般方法会超时,所以在网上查阅相关资料后,得到的初步结果是有三种方法:
第一种:普通方法,暴力破解,依次判断,时间复杂度o(n)
第二种:开方求解,时间复杂度o(squart(n))(本题参考第二种)
第三种:根据质数的分布规律,没看明白,原文连接
今日感想:学会忙里偷闲、学会苦中作乐。