蓝桥杯省赛真题2013年第四届Java本科B组第08题——幸运数

蓝桥杯省赛真题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;
	}
}

评测详情

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43594119/article/details/108753481