【编程马拉松】【001-NowCoder猜想】

【编程马拉松算法目录>>>】


【001-NowCoder猜想】【工程下载>>>】


1 题目描述


  nowcoder在家极度无聊,于是找了张纸开始统计素数的个数。设函数f(n)返回从1-n之间素数的个数。nowcoder 发现:

  f(1) = 0
  f(10) = 4
  f(100) = 25
  …
  满足g(m) = 17 * m^2 / 3 - 22 * m / 3 + 5 / 3
  其中m为n的位数。

  他很激动,是不是自己发现了素数分布的规律了!
  请你设计一个程序,求出f(n),来验证nowcoder是不是正确的,也许还可以得诺贝尔奖呢。^_^

1.1 输入描述:


  输入包括多组数据。
  每组数据仅有一个整数n (1≤n≤10000000)。

1.2 输出描述:


  对于每组数据输入,输出一行,为1->n(包括n)之间的素数的个数。

1.3 输入例子:


1
10
65
100
0

1.4 输出例子:


0
4
18
25

2 解题思路


  采用标记法求素数个数,假如输入是100,求100的平方根,得到10,再开辟大小为101的数组空间,将先将2倍数,但不包括2标记为非素数。现找下一个未标记的素数3,将3倍数,但不包括3标记为非素数。以此类推直到找到的素数大于10为止。最后统计未标记的数,那些数就是所求的素数。图2-1是以内的质数求解方法。
这里写图片描述
  图2-1 100 以内的质数求解

3 算法实现


import java.util.Scanner;

/**
 * Author: 王俊超
 * Date: 2016-01-13 13:54
 * CSDN: http://blog.csdn.net/derrantcm
 * Github: https://github.com/Wang-Jun-Chao
 * All Rights Reserved !!!
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//        Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            if (n >= 1 && n <= 10_000_000) {
                System.out.println(guess(n));
            }
        }

        scanner.close();
    }

    /**
     * 求[1, n]中素数的个数,使用标记法
     *
     * @param n 最大的范围
     * @return 素数个数
     */
    private static int guess(int n) {

        // 标记是否是素数
        // false表示是素数
        // true表示不是素数
        boolean[] mark = new boolean[n + 1];

        mark[0] = true;
        mark[1] = true;

        // 标记质数
        for (int i = 2; i < mark.length; i++) {
            // i是质数
            if (!mark[i]) {
                for (int j = 2 * i; j < mark.length; j += i) {
                    mark[j] = true;
                }
            }
        }

        // 统计质数个数
        int count = 0;
        for (int i = 2; i < mark.length; i++) {
            if (!mark[i]) {
                count++;
            }
        }

        return count;
    }
}

4 测试结果


这里写图片描述

5 其它信息


因为markddow不好编辑,因此将文档的图片上传以供阅读。Pdf和Word文档可以在Github上进行【下载>>>】。

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值