当前位置:   article > 正文

蓝桥杯刷题笔记 — 日期题目集合_小蓝发现了一个神奇的闹钟,从纪元时间(1970 年 1 月 1 日 00:00:00 )开 始,每经

小蓝发现了一个神奇的闹钟,从纪元时间(1970 年 1 月 1 日 00:00:00 )开 始,每经过

前言

作为一名java的小白,第一次参加蓝桥杯有点紧张,这些天学习的日子还是有些迷茫的。接下来会写一段时间的分类集合,把一些简单题尽量过掉,难的后面慢慢学吧,哎,心累。如果有写的不对的地方,大家可以提出来一起学习,一起进步。今天写的是日期题目模板。日期题目近年来在蓝桥杯竞赛中还是个香饽饽,咱还是尽量把这部分分拿到手,关键是这部分题也不难,都是模板类的一些个套路,接下来就一起看看吧。

 


目录

1. 含2天数

2. 完全日期

3. 星期几

4. 星期计算

5.小蓝跑步

时间模拟器提取

总结​


1. 含2天数

含2天数

 小蓝特别喜欢 2,今年是公元 2020 年,他特别高兴,因为每天日历上都可以看到 2。如果日历中只显示年月日,请问从公元 1900 年 1 月 1 日到公元 9999 年 12 月 31 日,一共有多少天日历上包含 2。即有多少天中年月日的数位中包含数字 2。

分析

首先,我们看到时间是公元1900.1.1~9999.12.31; 看到这个时间比较早,我们首先想到的肯定是用calendar,但是我们要知道的是calendar是从1970年1月1日00:00 00:00.000 的Epoch的偏移量(api这么写的),反正就是不能用日历了,那么我们就要写一个时间模拟器,每一天d++,到了一个月就m++,到了一年就y++; 这样我们每次做时间类的题目都可以套用这个模板,遇到条件不同改一下check函数就好啦。具体的代码如下:(文末也会提取一个时间模拟器代码出来)

  1. public class 含2天数 {
  2. static int y = 1900, m = 1,d = 1; //分别代表年,月,日
  3. static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //代表十二个月份
  4. public static void main(String[] args) {
  5. //日期模拟器
  6. int ans = 0; //记录日期中含有2的日期有多少个
  7. //当y=9999 && m=12 && d=31的时候返回不执行以下语句
  8. while(y != 9999 || m != 12 || d!= 31)
  9. {
  10. //判断是否是闰年
  11. if(y % 400 == 0 || (y%4 == 0 && y%100 != 0)) w[2] = 29;
  12. else w[2] = 28; //这里要记得改回原来的值,不然后面就一直是闰年了
  13. //如果日期中含有2,就记录答案
  14. //先判断,再让日期++ 到最后一天,其实已经结束循环了
  15. if(check()) ans++;
  16. d++;
  17. //接下来日期变更
  18. if(d > w[m])
  19. {
  20. m++;
  21. d = 1;
  22. }
  23. if(m > 12)
  24. {
  25. y++;
  26. m = 1;
  27. }
  28. }
  29. System.out.println(ans+1);
  30. }
  31. //判断日期中是否有2
  32. static boolean check()
  33. {
  34. int a = y; //因为a是全局变量,不能直接对y进行操作,a为成员变量
  35. while (a>0) {
  36. if (a % 10 == 2) return true;
  37. a /= 10;
  38. }
  39. int b = m; //因为m是全局变量,不能直接对y进行操作
  40. while (b > 0) {
  41. if (b % 10 == 2) return true;
  42. b /= 10;
  43. }
  44. int c = d; //因为d是全局变量,不能直接对y进行操作
  45. while(c > 0){
  46. if (c % 10 == 2) return true;
  47. c /= 10;
  48. }
  49. return false;
  50. }
  51. }

2. 完全日期

完全日期

如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日期。

例如:2021 年 6 月 5 日的各位数字之和为 2 + 0 + 2 + 1 + 6 + 5 = 162+0+2+1+6+5=16,而 16 是一个完全平方数,它是 4 的平方。所以 2021 年 6 月 5 日是一个完全日期。

例如:2021 年 6 月 23 日的各位数字之和为 2 + 0 + 2 + 1 + 6 + 2 + 3 = 162+0+2+1+6+2+3=16,是一个完全平方数。所以 2021 年 6 月 23 日也是一个完全日期。请问,从 2001 年 1 月 1 日到 2021 年 12 月 31 日中,一共有多少个完全日期?

分析

这也是一个日期区间的题目,直接套用时间模拟器,然后在check函数里判断这个日期是不是完全日期,如果是,就将答案记录下来。代码如下:

  1. public class 完全日期 {
  2. static int y = 2001, m = 1, d = 1; //年,月,日
  3. static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  4. public static void main(String[] args) {
  5. //时间模拟器
  6. //当y=2021 && m=12 && d=31的时候退出循环
  7. int ans = 0;//记录答案
  8. while( y!= 2021 || m != 12 || d!= 31 )
  9. {
  10. //判断是否是闰年
  11. if(y%400 == 0 || (y%4==0 && y%100!=0)) w[2] = 29;
  12. else w[2] = 28;
  13. //判断是否是完全日期
  14. if(check()) ans++;
  15. d++;
  16. //日期变更
  17. if(d > w[m])
  18. {
  19. m++;
  20. d=1;
  21. }
  22. if(m>12)
  23. {
  24. y++;
  25. m=1;
  26. }
  27. }
  28. System.out.println(ans);
  29. }
  30. static boolean check()
  31. {
  32. int a = y;//变量转换
  33. int sum = 0;
  34. while(a>0)
  35. {
  36. sum += a%10; //这里只是sum取了a值的最后一位,a并没有改变
  37. a /= 10;//依次将最后一位舍弃掉
  38. }
  39. int b = m;
  40. while(b > 0)
  41. {
  42. sum += b%10;
  43. b /= 10;
  44. }
  45. int c = d;
  46. while(c>0)
  47. {
  48. sum += c%10;
  49. c /= 10;//依次将最后一位舍弃掉
  50. }
  51. int v = (int)Math.sqrt(sum);//这个函数表示开平方
  52. if(v*v == sum) return true;
  53. return false;
  54. }
  55. }

3. 星期几

星期几

1949 年的国庆节( 10 月 1 日)是星期六。今年(2012)的国庆节是星期一。那么,从建国到现在,有几次国庆节正好是星期日呢?不要求写出具体是哪些年,只要一个数目!

分析

这是一道时间模拟器+记录星期几的题目,在这一个集合中,我也会把关于星期判断的题目理一下,具体的判断方法和过程我都写在了代码里,代码如下:

  1. public class 星期几 {
  2. static int y=1949, m=10, d=1;
  3. static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  4. static int t = 6; //表示星期几 注意:星期天是0;这里从星期六开始
  5. public static void main(String[] args) {
  6. int ans = 0; //记录答案
  7. //日期模拟器
  8. while (y != 2012 || m != 10 || d != 1)
  9. {
  10. //判断是否是闰年
  11. if(y%400 == 0 || (y%4 == 0 && y%100 !=0)) w[2] = 29;
  12. else w[2] = 28;
  13. //判断国庆节正好是星期日;t++;每天都判断一下
  14. if(check()) ans++;
  15. d++;
  16. t++;
  17. //日期变更
  18. if(d > w[m])
  19. {
  20. m++;
  21. d = 1;
  22. }
  23. if(m>12)
  24. {
  25. y++;
  26. m = 1;
  27. }
  28. }
  29. System.out.println(ans);
  30. }
  31. static boolean check()
  32. {
  33. if(t%7 == 0 && m == 10 && d == 1) return true;
  34. return false;
  35. }
  36. }

4. 星期计算

星期计算

已知今天是星期六,请问 20^22 天后是星期几? 注意用数字 1 到 7 表示星期一到星期日。

分析

这是十三届蓝桥杯的一道真题,考的是星期计算,我们也将它归为日期计算的一类题目,虽然这个题目并没有用到时间模拟器,但是实现思路也差不多,我们知道一个星期是7天,那么我们对将数字对7取余数(%7),如果余数是1就是星期一;是0就是星期天。有了这个基础后,我们假设今天是星期一,先计算出20^22是星期几;然后加上6天对7取余,就得到真正星期。这里有个小技巧,如果我们直接计算20^22会超出int的范围,我们引入数学上的一个知识  :例子:(20 * 20)mod 7= 20 mod 7 * 20 mod 7 或者 (20 mod 7) * (20 mod 7)mod 7;有了这个,我们就可以直接用一个for循环来依次计算到20的22次方。代码如下:

  1. public class 星期计算{
  2. public static void main(String[] args){
  3. int mod7 = 1; //设置一个mod7变量来存储值
  4. for(int i = 1; i <= 22; i++)
  5. mod7 = mod7 * 20 % 7;//计算出星期几
  6. mod7 = (mod7 + 6) % 7; //计算出六天后是星期几
  7. if(mod7 == 0){
  8. System.out.println(7);
  9. }else{
  10. System.out.println(mod7);
  11. }
  12. }
  13. }

5.小蓝跑步

小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米,如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。小蓝跑步已经坚持了很长时间。从2000年1月1日周六(包含)到2020年10月1日(包含)。请问这段时间小蓝总共跑步多少千米?

分析

这道题可以用时间模拟器,也可以用calendar来写,用calendar会比较快捷方便,两种方法都要好好掌握。细节都写在了代码里,代码如下:

时间模拟器方法:

  1. public class 小蓝跑步 {
  2. static int y=2000,m=1,d=1,t=6;
  3. static int[] w = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
  4. public static void main(String[] args) {
  5. int ans = 0;//记录答案
  6. //时间模拟器,因为10月1号要包含,所以我们自动加上一天,最后一天是不计入循环的
  7. while(y != 2020 || m != 10 || d!= 2){
  8. //判断是否是闰年
  9. if(y%400 == 0 || (y%4 == 0 && y%100 != 0)) w[2] = 29;
  10. else w[2]=28; //记得这里一定要变回来
  11. int n = t%7;
  12. if(n==1 || d==1){ ans+= 2;}
  13. else ans++;
  14. d++;
  15. t++;
  16. //时间变更
  17. if(d > w[m]){
  18. m++;
  19. d=1;
  20. }
  21. if(m>12){
  22. y++;
  23. m=1;
  24. }
  25. }
  26. System.out.println(ans);
  27. }
  28. }

Calendar方法:

  1. public class 小蓝跑步2 {
  2. public static void main(String[] args) {
  3. Calendar cstart = Calendar.getInstance(); //Calendar提供了一种类方法getInstance,用于获取此类型的一般有用的对象。
  4. cstart.set(2000,0,1); //注意:Calendar里1月份为0; 比较特殊
  5. Calendar cend = Calendar.getInstance();
  6. cend.set(2020,9,1); //注意:1月份从0开始的,所以这里到9月份就结束了。
  7. int ans = 0; // 记录答案(answer)
  8. while (cstart.compareTo(cend) <= 0){
  9. //外国算星期 星期天=1; 星期一=2
  10. if(cstart.get(Calendar.DAY_OF_MONTH)==1 || cstart.get(Calendar.DAY_OF_WEEK)==2)
  11. {
  12. ans += 2;
  13. }
  14. else ans+=1;
  15. cstart.add(Calendar.DATE,1); //模拟日历翻一天
  16. }
  17. System.out.println(ans);
  18. }
  19. }

具体的API方法提取:

DATEget或set的编号表示该月的日期
DAY_OF_MONTHget/set 本月的日期
DAY_OF_WEEKget/set 一周中的日期
add(int field, int amount)将指定的日历量增加或减去给定的日历字段
compareTo(Calendar )比较时间值Calendar对象
get(int field)返回给定日历字段的值
toString()返回此日历的字符串表示形式

时间模拟器提取

  1. //时间模拟器
  2. int y = 2001, m = 1, d = 1; //年,月,日
  3. int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  4. while( y!= 2021 || m != 12 || d!= 31 )
  5. {
  6. //判断是否是闰年
  7. if(y%400 == 0 || (y%4==0 && y%100!=0)) w[2] = 29;
  8. else w[2] = 28;
  9. d++;
  10. //日期变更
  11. if(d > w[m])
  12. {
  13. m++;
  14. d=1;
  15. }
  16. if(m>12)
  17. {
  18. y++;
  19. m=1;
  20. }
  21. }

总结

对于时间类的题目差不多就到这里了,如果要更加熟练运用的话还需要多多练题测试,以免出现细节上的错误,对于Calendar有需要熟练掌握使用,毕竟快嘛。这一期的总结就到这里啦!大家觉得有用的话也可以收藏,一起继续加油叭!


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/436024
推荐阅读
相关标签
  

闽ICP备14008679号