居左


私信TA

用户名:JZ50

访问量:75712

签 名:

楼下你的分数已经再次被超越!!快刷!!

等  级
排  名 34
经  验 14138
参赛次数 2
文章发表 109
年  龄 0
在职情况 学生
学  校 99
专  业

  自我简介:

TA的其他文章

解题思路:
    

    1. 设一个数为n,若n为非素数,则n存在因子在( 2...sqrt(n) ) (常规解法,速度较快),但循环时依然从2到sqrt(n), 当n较大时,内循环的次数较多。实际上,在2...sqrt(n)的循环过程中,只有当被除数为素数时才会被执行。故,先使用数组存储2...sqrt(n)之间的素数,记为a.

    2. 循环L到R的过程中,偶数必然为非素数,故只循环奇数,循环次数可减少一半。

    3. 循环L到R的奇数时,内循环只判断数组a内的数据是否能被指定的数整除。


综上所述:从内外循环减少复杂度,可达到题目时间要求。
    



注意事项:

    2<=L<=R<=1000000000,R-L<=1000000

    测试数据:999000000 1000000000

    本机测试时间在 1.5s内, 但是不能AC本题,不知道什么原因,有清楚的麻烦告知一声。

参考代码:

import java.util.Scanner;

public class C1790 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int L = sc.nextInt(), R = sc.nextInt();
			
			//long t1 = System.currentTimeMillis();
			
			int maxSqrt = (int)Math.sqrt(R);
			int len = 1;
			if(maxSqrt - 2 >= 0){
				len = maxSqrt - 2 + 1;
			}
			
			int[] a = new int[len];
			int k = 0;
			for(int n = 2; n <= maxSqrt; n++){
				boolean isSu = true;
				for(int i = 2; i*i <= n; i++){
					if(n % i == 0){
						isSu = false;
						break;
					}
				}
				if(isSu){
					a[k++] = n;
				}
			}
			
			int count = 0;
			if(L <= 2){
				count++;
				L = 3;
			}else if(L % 2 == 0){
				L += 1;
			}
			for(int n = L; n <= R; n+=2){
				boolean isSu = true;
				for(int i = 0; i < a.length && a[i] > 0 && n != a[i]; i++){
					if(n % a[i] == 0){
						isSu = false;
						break;
					}
				}
				if(isSu){
					count++;
				}
			}
			System.out.println(count);
			
			//long t2 = System.currentTimeMillis();
			//System.out.println(t2-t1);
		}
		sc.close();
	}
}


 

0.0分

0 人评分

  评论区

你的代码不能ac的原因是因为本题是并不是一组测试数据,而是多组测试数据在同一个文件里,大概10组吧,如果你一组要跑1.5s 那么10组就超时了。所以你的方法还有待改进,这个题是这套题里最难的一道,出这个题的本意是希望你能采用nlogn的算法的,具体思路可以查看我的10月月赛题解。
2018-05-28 19:15:07
  • «
  • 1
  • »