幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。
首先从1开始写出自然数1,2,3,4,5,6,.... 1 就是第一个幸运数。 我们从2这个
数开始。把所有序号能被2整除的项删除变为
1 _ 3 _ 5 _ 7 _ 9 ....
把它们缩紧重新记序为 1 3 5 7 9 .... 。这时3为第2个幸运数然后
把所有能被3整除的序号位置的数删去。注意是序号位置不是那个数本身能
否被3整除!! 删除的应该是511, 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 < 1000*1000)程序输出 位于m和n之间
的幸运数的个数不包含m和n。
例如用户输入1 20程序输出5
例如用户输入30 69程序输出8
代码如下:
public class Main{
public static void f(int m, int n, int[] a){
int k = m; //k表示每一轮从数组a哪个下标开始判断。
int t = a[m]; //t表示每一次要被取余判断的元素。
for(int i=m; i<n; i++) {
if((i+1)%t!=0) { //i+1表示从选定被整除元素的下一个元素开始判断
a[k]=a[i]; //修改数组a中的元素,并使k++;
k++;
}
}
if(t<n) f(m+1, n, a); //注意这里是t不是m
}
public static void g(int m, int n, int[] a) {
int count = 0;
for(int i=0; i<a.length; i++) {
if(a[i]>m && a[i]<n) count++;
}
System.out.println(count);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int[] a = new int[n];
for(int i=0; i<n; i++) {
a[i] = 2*i+1;
}
//求出到n的所有的幸运数
f(1, n, a);
g(m, n, a);
}
}
这里的f函数是求出到给定的n的所有的幸运数的集合,放在a中。注意f函数递归的判断条件是t < n,t表示的是要被取余的那个数,不是m<n,因为a[m]比m大,写成m数组会越界异常。

本文介绍了一种使用递归筛选法生成并查找指定区间内的幸运数的方法。幸运数由波兰数学家乌拉姆提出,其生成过程类似于素数的筛选过程。通过递归函数f实现幸运数的筛选与存储,再利用g函数统计指定区间内幸运数的数量。
1118

被折叠的 条评论
为什么被折叠?



