【PAT】乙级1007素数对猜想(JAVA版)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class PAT1007 {

	public static List<Integer> suShu(int max){
		int i=0;int j=0;
		List<Integer> list=new ArrayList<Integer>();
		if(max==2) {
			list.add(2);
		}
		if(max>=3) {
			list.add(2);
			for(i=3;i<=max;i+=2) {
				boolean flag=true;
				for(j=3;j*j<=i;j+=2) {
					if(i%j==0) { 
						flag=false;
						break;
					}
				}
				if(flag==true)
					list.add(i);
			}
		}
		return list;
	}
	
	public static void main(String[] args) throws IOException {
		List<Integer> list=new ArrayList<Integer>(0);
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		list=suShu(Integer.parseInt(br.readLine()));
		int count=0;
		for(int i=0;i<list.size()-1;i++) {
			if(list.get(i+1)-list.get(i)==2) { 
				count++;
			}
		}
		System.out.println(count);
	}
}

第一次遇到“运行超时”

注意点:

1、在进行素数的判断的时候,应该i>=max,不然如果max就是素数的话,会判断不到max,然后会少一个素数

2、注意flag声明的位置,应该放在附一个循环的里面、第二个循环的上面。如果放在第一个循环的外面,那么flag在被改为false之后,就一直是false了

3、使用BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));

 list=suShu(Integer.parseInt(br.readLine()));

比Scanner更节省时间

 

收集了一些运算素数的方法(六个方法)

1、根据定义,使用循环,测试数有没有因子

public boolean isPrime(int n)

{

    if(n < 2) return false;

    for(int i = 2; i < n; ++i)

    if(n%i == 0) return false;

    return true;

}

时间复杂度O(n).

2、去掉偶数

public boolean isPrime(int n)

{

if(n < 2) return false;

if(n == 2) return true;

if(n%2==0) return false;

for(int i = 3; i < n; i += 2)

if(n%i == 0) return false;

return true;

}

时间复杂度O(n/2), 速度提高一倍.

3、使用定理

定理: 如果n不是素数, 则n有满足1< d<=sqrt(n)的一个因子d.

证明: 如果n不是素数, 则由定义n有一个因子d满足1< d< n.

如果d大于sqrt(n), 则n/d是满足1< n/d<=sqrt(n)的一个因子.

public boolean isPrime(int n)

{

if(n < 2) return false;

if(n == 2) return true;

if(n%2==0) return false;

for(int i = 3; i*i <= n; i += 2)

if(n%i == 0) return false;

return true;

}

时间复杂度O(Math.sqrt(n)/2), 速度提高O((n-Math.sqrt(n))/2).

4、剔除因子中的重复判断

定理: 如果n不是素数, 则n有满足1< d<=Math.sqrt(n)的一个"素数"因子d.

证明: I1. 如果n不是素数, 则n有满足1< d<=Math.sqrt(n)的一个因子d.

I2. 如果d是素数, 则定理得证, 算法终止.

I3. 令n=d, 并转到步骤I1.

由于不可能无限分解n的因子, 因此上述证明的算法最终会停止.

// primes是递增的素数序列: 2, 3, 5, 7, ...

// 更准确地说primes序列包含1->Math.sqrt(n)范围内的所有素数

public boolean isPrime(int primes[], int n)

{

if(n < 2) return false;

for(int i = 0; primes[i]*primes[i] <= n; ++i)

if(n%primes[i] == 0) return false;

return true;

}

5、构造素数序列primes:2,3,5,7,。。。。

由4的算法我们知道, 在素数序列已经被构造的情况下, 判断n是否为素数效率很高;

下面程序可以输出素数表.

public class ShowPrimeNumber{

public static int[] getPrimeNums(int maxNum){

int[] primeNums = new int[maxNum/2+1];

int sqrtRoot;

int cursor = 0;

boolean isPrime;

for(int i=2;i<=maxNum;i++){

sqrtRoot = (int)Math.sqrt(i); //取平方根

isPrime = true;

for(int j=0;j< cursor;j++){

if(primeNums[j]>sqrtRoot)

break;

if(i%primeNums[j]==0){

isPrime = false;

break;

}

}

if(isPrime){

primeNums[cursor++] = i;

}

}

int[] result = new int[cursor];

System.arraycopy(primeNums,0,result,0,cursor);

return result;

}

public static void main(String[] args) throws Exception{

int maxNum = Integer.parseInt(args[0]);

int[] primeNums = getPrimeNums(maxNum);

System.out.println("共"+primeNums.length+"个素数");

for(int i=0;i< primeNums.length;i++){

System.out.print(primeNums[i]+",\t");

}

}

}

6、在素数表中进行二分查找

Arrays.BinarySearch方法:

该方法用于在指定数组中查找给定的值,采用二分法实现,所以要求传入的数组已经是排序了的。

该方法的基本语法格式为:

Static int binarySearch(byte[] a, byte key)

该方法返回数据中key元素所在的位置,如果没有key元素,则返回key应插入的位置:-(insertion point-1),如数组中的第一个元素就大于key,返回-1。

注:数组的数据类型可以是int[] byte[] short[] float[] long[] double[] char[] Object[]类型。

 

判定系统非常的随缘,有的时候编译超时,有的时候编译就不超时;同一个程序,运气好就不超时,运气不好就超时。我F.....佛慈悲(手动笑脸)

根据引用\[1\]和引用\[2\]的代码,这是一个关于判断素数和计算素数对的问题。代码中使用了循环和条件判断来判断一个数是否为素数,并计算相邻素数之间差为2的素数对的数量。具体的代码逻辑如下: 1. 首先,通过输入一个正整数n来确定素数的范围。 2. 然后,使用循环从3开始遍历到n,判断每个数是否为素数。 3. 在判断素数的过程中,使用了一个内层循环和条件判断来判断一个数是否能被其他数整除,如果能整除则不是素数。 4. 如果一个数通过了判断是素数,则将其存入数组a中。 5. 最后,再次遍历数组a,判断相邻素数之间的差是否为2,如果是则计数器sum加1。 6. 最后输出sum的值,即为相邻且差为2的素数对的数量。 根据题目要求,输入样例为20,输出样例为4,即在1到20的范围内,存在4对相邻且差为2的素数。因此,根据给定的代码,输出结果应为4。 #### 引用[.reference_title] - *1* [PAT乙级-1007 素数猜想- C语言实现(代码详解+知识点归纳)](https://blog.csdn.net/m0_61704394/article/details/124017780)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [PAT乙级C语言1007 素数猜想](https://blog.csdn.net/li_yizhixiaowukong/article/details/88072233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值