【每日蓝桥】16、一三年省赛Java组真题“幸运数”

114

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

你好呀,我是灰小猿,一个超会写bug的程序猿!

欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!

标题:幸运数

幸运数是波兰数学家乌拉姆命名的,它采用与生成素数相同的“筛法”生成

首先从1开始写出自然数1、2、3、4、5、6......

1就是第一个幸运数

我们从2这个数开始,把所有序号能被2整除的项删除,变为:

1_3_5_7_9.......

把他们缩紧,重新记序,为:

1 3 5 7 9......这时3为第二个幸运数,然后把所有能被3整除的序号位置的数删去,

注意:是序号位置,不是那个数本身能否被3整除!!整除的应该是5、11、17...

此时7为第三个幸运数,然后再删去序号位置能被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

解题思路:

本题在解题上,根据题意我们可以先获取到经过一次筛选后得到数组,即只有奇数的数组,我们可以将该数组作为起始数组,根据幸运数的筛选规律,再进行之后的筛选,同时对于删去的数,我们需要将之后没有删除的数填补上去,直到幸运数字的下标是等于数组的长度时,这个时候就不能够再删除,然后从最终得到的数组中找出在m和n之间的数的个数即可。

答案源码:

package 一三年省赛真题;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Year2013_Bt8 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int m = scanner.nextInt();
		int n = scanner.nextInt();
		int[] arr = new int[n];
		//进行第一轮筛选,剔除所有的偶数
		for (int i = 0; i < n; i++) {
			arr[i] = 2*i+1;
		}
		
		int s = 1;	//记录幸运数的下标
		while (s<=arr.length) {
			int p = s+1;	//记录数前移到的下标
			for (int i = s+1; i < arr.length; i++) {
				//如果该数所处的序号能够被幸运数整除
				if ((i+1)%arr[s]==0) {
					
				}else {	//如果该数所处的序号不能够被幸运数整除,那么该数应该前移,
					arr[p] = arr[i];
					p++;
				}
				if (arr[i]>n) {
					break;
				}
			}
			s++;	//每排列一次,幸运数的下标加1
		}
		
		int count=0;	//记录个数
		for (int i = 0; i < arr.length; i++) {
			if (arr[i]>m&&arr[i]<n) {	//找出位于m和n之间的幸运数,并记录个数
				count++;
			}
			if (arr[i]>=n) {
				break;
			}
		}
		System.out.println(count);
	}

}

输出样例:

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!