蓝桥杯省赛真题2013年第四届Java本科B组
第08题——幸运数
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。
首先从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 < 1000*1000)
程序输出 位于m和n之间的幸运数的个数(不包含m和n)。
例如:
用户输入:
1 20
程序输出:
5
例如:
用户输入:
30 69
程序输出:
8
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
思路
第一次筛选没什么特别的,就是留下奇数,所以可以上来就给数组附上奇数
然后就是循环筛选每次幸运数的下标往前走一个,这个数就是对应的幸运数,让数字位置可以被其整除的数改为0,然后调缩紧函数进行缩紧即可。
注意这里只要幸运数比当前数的总数小,那么就得继续筛选。
代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int count = 0; //记录幸运数的个数
int lucky = 0; //记录幸运数下标
int []a = new int[(n+1)/2]; //根据题意第一次全是奇数,数组长度为n的一半
//第一次筛选,全放奇数即可
for (int i = 0; i < a.length; i++) {
a[i]=2*i+1;
}
while(a[lucky]<=a.length) {
lucky++; //幸运数下标往右走一个
//第n次筛选,把所有位置能被幸运数整除赋值为0,便于缩紧函数缩紧
for (int i = 0; i < a.length; i++) {
if ((i+1)%a[lucky]==0) {
a[i] = 0;
}
}
//缩紧
a = suojin(a);
}
//统计m和n之间的幸运数的个数
for (int i = 0; i < a.length; i++) {
if (a[i]>=n) {
break;
}
if (a[i]>m) {
count++;
}
}
// for (int i : a) {
// System.out.print(i+" ");
// }
// System.out.println();
System.out.println(count);
}
//缩紧函数
private static int[] suojin(int[] arr) {
int right = arr.length-1;
int count_0 = 0; //记录0的个数
//统计零的个数用来对数组进行切割
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
count_0++;
}
}
for (int i = 0; i < arr.length; i++) {
//一旦这个元素为0,那么就把它和最后面不为零的元素互换
if (arr[i]==0) {
//确保右边界的元素不为零
while (arr[right]==0 && i<right) {
right--;
}
//和不为零的元素互换
int temp = arr[right];
arr[right] = arr[i];
arr[i] = temp;
right--;
}
if (right<=i) {
break;
}
}
//创建一个新的数组,舍去末尾的一串0
int[] arr2 = new int[arr.length-count_0];
for (int i = 0; i < arr2.length; i++) {
arr2[i] = arr[i];
}
//进行排序
Arrays.sort(arr2);
return arr2;
}
}