1007 素数对猜想 (20分)
题目
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
思路
- 题目要求是输入一个数,然后找出这个0到这个数字中的素数,并且找出两个素数相临为2的个数
- 步骤是先求出0到输入数中的素数,字符串形式存放以空格隔开,并且在统计数素数的个数
- 然后转为数组,遍历数组,判断条件
代码(版本一)
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
in.close();
String str1 = "";
String str2 = "";
int size1 = 0 ;
int size2 = 0 ;
if(num == 0 || num == 1) {
System.out.println(0);
return;
}
int index = 2;
while(true) {
if(isTrue(index)) {
if(index > 0 && index<=4000) {
str1 = str1 + (index + " ");
size1 ++;
}else if(index > 4000 && index < 10000) {
str2 = str2 + (index + " ");
size2 ++;
}
}
if(index == num) {
break;
}
index ++;
}
String[] arr1 = str1.split("\\s+");
int[] numArr1 = new int[size1];
for(int i = 0 ; i < arr1.length ; i ++) {
numArr1[i] = Integer.parseInt(arr1[i]);
}
if(str2.length() != 0) {
int[] numArr2 = new int[size2];
String[] arr2 = str2.split("\\s+");
for(int i = 0 ; i < arr2.length ; i ++) {
numArr2[i] = Integer.parseInt(arr2[i]);
}
if(numArr2[0] - numArr1[numArr1.length - 1] == 2) {
System.out.println(haveTrue(numArr1) + haveTrue(numArr2) + 1);
}
System.out.println(haveTrue(numArr1) + haveTrue(numArr2));
return;
}
System.out.println(haveTrue(numArr1));
}
//统计个数
public static int haveTrue(int[] arr) {
int temp = 0;
for(int i = 0 ; i < arr.length - 1 ; i ++) {
if(arr[i+1] - arr[i] == 2) {
temp ++;
}
}
return temp;
}
//判断是否为素数
public static boolean isTrue(int a) {
if(a==1){
return false;
}
if(a%2==0&&a!=2){
return false;
}
for(int i=3;i<=Math.sqrt(a);i+=2){
if(a%i==0){
return false;
}
}
return true;
}
}
完成度
80 %
总结
最后一个测试运行超出内存,改良以后答案错误(找不到这个bug)
说明一下运行超出内存问题:这个版本的代码思想是把素数用一个数组存放,然后对i
和i + 1
的素数进行条件判断,
当时没有考虑到数组的大小,由于9999以内有1229个素数,所以数组存放数据过大,于是我改良了代码,创建了两个数组来存放,这样就解决了内存问题;
第二版本
由来
由于第一版本最后的答案不真确,找室友大佬帮我看了一下,然后他提出了我没有想到的方法,于是有了第二个版本
思考
- 判断这个数是不是素数,如果是,
+2
以后再判断新的数是不是素数,是的话满足条件++
- 嗯~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 大佬就是大佬
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/*-------------------------------第一种方法--------------------------------------*/
Scanner in = new Scanner(System.in);
int num = in.nextInt();
in.close();
if(num == 0 || num == 1) {
System.out.println(0);
return;
}
int size = 0;
for(int i = 2 ; i < num ; i ++) {
if(isTrue(i)) {
if(i + 2 <= num &&isTrue(i+2)) {
size ++;
}
}
}
System.out.println(size);
}
//判断是否为素数
public static boolean isTrue(int a) {
if(a==1){
return false;
}
if(a%2==0&&a!=2){
return false;
}
for(int i=3;i<=Math.sqrt(a);i+=2){
if(a%i==0){
return false;
}
}
return true;
}
}
完成度
100%
总结
循环传值判断这个值是否是素数,如果是,再判断+2的数
if(isTrue(i)) {
if(i + 2 <= num &&isTrue(i+2)) {
size ++;
}
}
内层条件,需要加上i + 2 <= num
用来控制下一个素数也在输入值里面