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 suShu(int max){
int i=0;int j=0;
List list=new ArrayList();
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 list=new ArrayList(0);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
list=suShu(Integer.parseInt(br.readLine()));
int count=0;
for(int i=0;i
第一次遇到“运行超时”
注意点:
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.....佛慈悲(手动笑脸)