幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。
首先从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数组会越界异常。