你好呀,我是灰小猿,一个超会写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); } }
输出样例: