一、世纪末的星期
题目描述
:
文字版:
曾有邪教称 1999 年 12 月 31 日是世界末日。当然该谣言已经不攻自破。
还有人称今后的某个世纪末的 12 月 31 日,如果是星期一则会…
有趣的是,任何一个世纪末的年份的 12 月 31 日都不可能是星期一!!
于是,“谣言制造商”又修改为星期日…
1999 年的 12 月 31 日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即 xx99 年)的 12 月 31 日正好是星期天(即星期日)?
请回答该年份(只写这个 4 位整数,不要写 12 月 31 等多余信息)
解题思路
:
Java解法比较简单,可以直接调用 Calendar 对象的相关方法:
① Calendar.set(int field, int value)
方法
② Calendar.get(int field)
方法
借助上述方法,我们就能轻松获取到某年某月某日是星期几了。
具体做法就是遍历1999年及以后的每一个世纪末年(XX99)的 12 月 31 日,借助get()方法获取当天是星期几,若正好是星期天则停止循环,并输出年份。
解题代码
:
import java.util.Calendar; public class 世纪末的星期 { public static void main(String[] args) { //使用Calender对象的getInstance()方法获取其对象 Calendar calendar = Calendar.getInstance(); for(int year = 1999;;year += 100) { //每个循环加100年。遍历所有世纪末 //set()获取年月日 calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, 11); //11代表十二月 calendar.set(Calendar.DAY_OF_MONTH, 31); //若世纪末为星期日(数字1),输出当前世纪末年份 if(calendar.get(Calendar.DAY_OF_WEEK) == 1) { System.out.println(calendar.get(Calendar.YEAR)); break; //停止循环 } } } }
二、幸运数
题目描述
:
文字版:
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的"筛法"生成。
首先从 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 <10^6)。
输出描述:
输出位于 m和n 之间的幸运数的个数(不包含 m 和 n )。
解题思路
:
按照题目描述,开始需要从1开始写出自然数,我们可以不做处理,从第一轮的“筛选”开始,
第一轮,只需要遍历数组下标,通过2i+1
的运算,即可获得1.3.5.7…的序列,
从第二轮开始,我们就需要重复地遍历最新“幸运数”
之后的数字,将能被“幸运数”
整除的序号位置的数删去,获取到新的序列。
这样的循环一直持续到最新的幸运数 >= 输入的整数n,
循环停止后,我们就获得了最新的序列,遍历序列,记录m和n之间的幸运数个数,输出即可~
解题代码
:
import java.util.Scanner; public class 幸运数 { public static void main(String[] args) { //输入 Scanner scan = new Scanner(System.in); //输入两个整数,分别为 m 、n int m = scan.nextInt(); int n = scan.nextInt(); //创建一个数组,用于存放序列 int[] arr = new int[n]; //记录m和n之间的幸运数个数 int count = 0; //第一轮,所有序号能被 2 整除的项删除 for(int i = 0;i < n;i++) { arr[i] = i*2+1; } //当前幸运数为3,下标index = 1 int index = 1; //设置无限循环 while(true) { //记录幸运数的下一位置 int p = index+1; //从幸运数的下一位置开始遍历 for(int j = index+1 ;j < n;j++) { //实际数字序位 即 下标+1, //能被当前幸运数整除 说明新的序列中不需要,故不做处理 if((j+1) % arr[index] == 0) { }else { //若新的序列中需要,放置到幸运数的下一位置。 //(新的幸运数产生,代表幸运数下一位置的p需要+1) arr[p++] = arr[j]; } } //新的序列生成,幸运数增加,幸运数下标+1 ++index; //若新的幸运数>=n,停止while循环 if(arr[index] >= n) break; } //遍历当前存放着最新序列的数组,记录m和n之间的幸运数个数 for(int i = 0;i < n;++i) { if(arr[i] > m && arr[i] < n) { count++; } } //输出 System.out.print(count); } }