赞
踩
目录
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的"筛法"生成。
首先从 1 开始写出自然数 1,2,3,4,5,6,⋯
1 就是第一个幸运数。
我们从 2 这个数开始。把所有序号能被 2 整除的项删除,变为:
1 3 5 7 9 ⋯
把它们缩紧,重新记序,为:
1 3 5 7 9 ⋯
这时,3 为第 2个幸运数,然后把所有能被 3 整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被 3 整除!!删除的应该是 5,11, 17,⋯
此时 7 为第 3 个幸运数,然后再删去序号位置能被 7 整除的( 19,39,⋯)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ⋯
输入两个正整数 m,n用空格分开 (m < n < 10^6)。
输出位于 m 和 n 之间的幸运数的个数(不包含 m 和 n )。
输入
1 20
输出
5
1.照例先分析题目,幸运数是从1开始的,一直往后,然后1是第一个自然数,就不管他,让第一个幸运数从2开始,就是删除所有下标能被2整除的数。
2.这里看到需要频繁删除,首先排除数组来做(用数组做也不是不行),可以用列表。
3.然后看数据范围,它给的提示是 m和n,但是幸运数是从1开始的,也就是说我们需要填充1到n的数据进列表里面。然后删除完毕之后再判断m-n范围内的数据有多少即可。
4.因为列表的特性(删除了i,那么i的位置就会被i+1补上),所以我们删除要从末尾开始,依次往前删除,也就是 从len 到 1;
5.循环读取幸运数删除即可,每次拿到幸运数,通过一个方法,逆向删除所有能被该幸运数整除的下标即可。
- import java.util.*;
- // 1:无需package
- // 2: 类名必须Main, 不可修改
-
- public class Main {
- public static void main(String[] args) {
- Scanner scan = new Scanner(System.in);
- //题目描述是很有问题,简单来说,就是这些幸运数是从1开始填充到N的,然后第一个幸运数为2,就是删除偶数位置的值
- //然后第二个幸运数就是列表中的第三个数(列表我们额外填充一个0,这样1的下标就是1,模拟出了题目的情况)
- int m = scan.nextInt();
- int n = scan.nextInt();
- scan.close();
- List<Integer> list = new ArrayList<>();
- //因为下标都是从0开始,我们为了模拟题目要求,多填充一个0
- list.add(0);
- //填充数据
- for(int i = 1;i<=n;i++){
- list.add(i);
- }
- //幸运数从1开始,直到列表的长度(超出列表的长度代表幸运数已经处理完了,接下来只需要统计m-n范围的数据即可)
- int luck = 1;
- while(luck<list.size()){
- //处理一开始的特殊情况(第一个幸运数是1,那么就顺延到下一个,也就是2)
- if(luck == 1){
- delete(list,2);
- }else{
- delete(list,list.get(luck));
- }
- luck++;
- }
- //删除完之后遍历一下看看list剩余
- int number = 0;
- for(int i : list){
- if(i>m && i<n){
- number++;
- }
- }
- System.out.println(number);
- }
- /*删除能被luck整除的下标*/
- public static void delete(List<Integer> list,int luck){
- //一般都是从末尾开始删除,不然会因为列表的特性(删了i位置的,i+1位置的会补上来)出错
- int len = list.size()-1;
- for(int i = len;i>0;i--){
- if(i%luck == 0){
- list.remove(i);
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。