zoukankan      html  css  js  c++  java
  • 使用欧拉筛解决素数计算问题

    转自: http://www.cnblogs.com/A-S-KirigiriKyoko/articles/6034572.html
    我们知道当一个数为素数的时候,它的倍数肯定不是素数。所以我们可以从2开始通过乘积筛掉所有的合数。
    将所有合数标记,保证不被重复筛除,时间复杂度为O(n)。

    public class Main {
        public static void main(String[] args) {
            int n = 100;// 输入的数
            int count = 0;
            int[] prime = new int[n + 1]; // 存储prime
            boolean[] vis = new boolean[n + 1]; // 标识是否是prime
            for (int i = 2; i <= n; i++) {
                if (!vis[i]) {
                    prime[count++] = i;
                    System.out.println(i);
                }
                for (int j = 0; j < count && i * prime[j] <= n; j++) {
                    vis[i * prime[j]] = true;
                    if (i % prime[j] == 0){ //如果i 是 4 它取余 prime[j] == 0 那么说明它的因数(除了它本身是刚刚设置的)的vis都被设置过了
    //                  System.out.println(i + " % " + prime[j]);
                        break;
                    }
                }
            }
        }
    }
    

    if(i % prime[j] == 0) break;←_←这一步比较难理解
    解释:
    首先,任何合数都能表示成多个素数的积。所以,任何的合数肯定有一个最小质因子。我们通过这个最小质因子就可以判断什么时候不用继续筛下去了。
    当i是prime[j]的整数倍时(i % prime[j] == 0),i*prime[j+1]肯定被筛过,跳出循环。
    因为i可以看做prime[j]某个数, i*prime[j+1]就可以看做 prime[j]某个数*prime[j+1] 。而 prime[j] 必定小于 prime[j+1],
    所以 i*prime[j+1] 必定已经被 prime[j]*某个数 筛掉,就不用再做了√
    同时我们可以发现在满足程序里的两个条件的时候,prime[j]必定是prime[j]*i的最小质因子。这个性质在某些题里可以用到。
    这样就可以在线性时间内找到素数啦~(≧▽≦)/~

  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1036. Boys vs Girls (25)
    1035 Password (20)
    1027 Colors in Mars (20)
    1009. Product of Polynomials (25)
    1006. Sign In and Sign Out
    1005 Spell It Right (20)
    1046 Shortest Distance (20)
    ViewPager页面滑动,滑动到最后一页,再往后滑动则执行一个事件
    IIS7.0上传文件限制的解决方法
  • 原文地址:https://www.cnblogs.com/chinashenkai/p/9451384.html
Copyright © 2011-2022 走看看