赞
踩
作为一名java的小白,第一次参加蓝桥杯有点紧张,这些天学习的日子还是有些迷茫的。接下来会写一段时间的分类集合,把一些简单题尽量过掉,难的后面慢慢学吧,哎,心累。如果有写的不对的地方,大家可以提出来一起学习,一起进步。今天写的是日期题目模板。日期题目近年来在蓝桥杯竞赛中还是个香饽饽,咱还是尽量把这部分分拿到手,关键是这部分题也不难,都是模板类的一些个套路,接下来就一起看看吧。
小蓝特别喜欢 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函数就好啦。具体的代码如下:(文末也会提取一个时间模拟器代码出来)
- public class 含2天数 {
- static int y = 1900, m = 1,d = 1; //分别代表年,月,日
-
- static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //代表十二个月份
-
- public static void main(String[] args) {
- //日期模拟器
- int ans = 0; //记录日期中含有2的日期有多少个
- //当y=9999 && m=12 && d=31的时候返回不执行以下语句
- while(y != 9999 || m != 12 || d!= 31)
- {
- //判断是否是闰年
- if(y % 400 == 0 || (y%4 == 0 && y%100 != 0)) w[2] = 29;
- else w[2] = 28; //这里要记得改回原来的值,不然后面就一直是闰年了
- //如果日期中含有2,就记录答案
- //先判断,再让日期++ 到最后一天,其实已经结束循环了
- if(check()) ans++;
- d++;
- //接下来日期变更
- if(d > w[m])
- {
- m++;
- d = 1;
- }
- if(m > 12)
- {
- y++;
- m = 1;
- }
- }
- System.out.println(ans+1);
- }
-
- //判断日期中是否有2
- static boolean check()
- {
- int a = y; //因为a是全局变量,不能直接对y进行操作,a为成员变量
- while (a>0) {
- if (a % 10 == 2) return true;
- a /= 10;
- }
-
- int b = m; //因为m是全局变量,不能直接对y进行操作
- while (b > 0) {
- if (b % 10 == 2) return true;
- b /= 10;
- }
-
- int c = d; //因为d是全局变量,不能直接对y进行操作
- while(c > 0){
- if (c % 10 == 2) return true;
- c /= 10;
- }
- return false;
- }
- }
如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日期。
例如: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函数里判断这个日期是不是完全日期,如果是,就将答案记录下来。代码如下:
- public class 完全日期 {
-
- static int y = 2001, m = 1, d = 1; //年,月,日
- static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
-
- public static void main(String[] args) {
- //时间模拟器
- //当y=2021 && m=12 && d=31的时候退出循环
- int ans = 0;//记录答案
- while( y!= 2021 || m != 12 || d!= 31 )
- {
- //判断是否是闰年
- if(y%400 == 0 || (y%4==0 && y%100!=0)) w[2] = 29;
- else w[2] = 28;
-
- //判断是否是完全日期
- if(check()) ans++;
- d++;
-
- //日期变更
- if(d > w[m])
- {
- m++;
- d=1;
- }
- if(m>12)
- {
- y++;
- m=1;
- }
- }
- System.out.println(ans);
- }
-
- static boolean check()
- {
- int a = y;//变量转换
- int sum = 0;
- while(a>0)
- {
- sum += a%10; //这里只是sum取了a值的最后一位,a并没有改变
- a /= 10;//依次将最后一位舍弃掉
- }
-
- int b = m;
- while(b > 0)
- {
- sum += b%10;
- b /= 10;
- }
-
- int c = d;
- while(c>0)
- {
- sum += c%10;
- c /= 10;//依次将最后一位舍弃掉
- }
-
- int v = (int)Math.sqrt(sum);//这个函数表示开平方
- if(v*v == sum) return true;
- return false;
- }
-
- }
1949 年的国庆节( 10 月 1 日)是星期六。今年(2012)的国庆节是星期一。那么,从建国到现在,有几次国庆节正好是星期日呢?不要求写出具体是哪些年,只要一个数目!
分析
这是一道时间模拟器+记录星期几的题目,在这一个集合中,我也会把关于星期判断的题目理一下,具体的判断方法和过程我都写在了代码里,代码如下:
- public class 星期几 {
- static int y=1949, m=10, d=1;
- static int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
- static int t = 6; //表示星期几 注意:星期天是0;这里从星期六开始
-
- public static void main(String[] args) {
- int ans = 0; //记录答案
- //日期模拟器
- while (y != 2012 || m != 10 || d != 1)
- {
- //判断是否是闰年
- if(y%400 == 0 || (y%4 == 0 && y%100 !=0)) w[2] = 29;
- else w[2] = 28;
-
- //判断国庆节正好是星期日;t++;每天都判断一下
- if(check()) ans++;
- d++;
- t++;
-
- //日期变更
- if(d > w[m])
- {
- m++;
- d = 1;
- }
- if(m>12)
- {
- y++;
- m = 1;
- }
- }
- System.out.println(ans);
- }
-
- static boolean check()
- {
- if(t%7 == 0 && m == 10 && d == 1) return true;
- return false;
- }
- }
-
已知今天是星期六,请问 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次方。代码如下:
- public class 星期计算{
- public static void main(String[] args){
- int mod7 = 1; //设置一个mod7变量来存储值
- for(int i = 1; i <= 22; i++)
- mod7 = mod7 * 20 % 7;//计算出星期几
- mod7 = (mod7 + 6) % 7; //计算出六天后是星期几
- if(mod7 == 0){
- System.out.println(7);
- }else{
- System.out.println(mod7);
- }
- }
- }
小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米,如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。小蓝跑步已经坚持了很长时间。从2000年1月1日周六(包含)到2020年10月1日(包含)。请问这段时间小蓝总共跑步多少千米?
分析
这道题可以用时间模拟器,也可以用calendar来写,用calendar会比较快捷方便,两种方法都要好好掌握。细节都写在了代码里,代码如下:
时间模拟器方法:
- public class 小蓝跑步 {
-
- static int y=2000,m=1,d=1,t=6;
- static int[] w = new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31};
-
- public static void main(String[] args) {
- int ans = 0;//记录答案
- //时间模拟器,因为10月1号要包含,所以我们自动加上一天,最后一天是不计入循环的
- while(y != 2020 || m != 10 || d!= 2){
- //判断是否是闰年
- if(y%400 == 0 || (y%4 == 0 && y%100 != 0)) w[2] = 29;
- else w[2]=28; //记得这里一定要变回来
-
- int n = t%7;
- if(n==1 || d==1){ ans+= 2;}
- else ans++;
- d++;
- t++;
- //时间变更
- if(d > w[m]){
- m++;
- d=1;
- }
- if(m>12){
- y++;
- m=1;
- }
- }
- System.out.println(ans);
- }
- }
Calendar方法:
- public class 小蓝跑步2 {
- public static void main(String[] args) {
- Calendar cstart = Calendar.getInstance(); //Calendar提供了一种类方法getInstance,用于获取此类型的一般有用的对象。
- cstart.set(2000,0,1); //注意:Calendar里1月份为0; 比较特殊
- Calendar cend = Calendar.getInstance();
- cend.set(2020,9,1); //注意:1月份从0开始的,所以这里到9月份就结束了。
- int ans = 0; // 记录答案(answer)
-
-
- while (cstart.compareTo(cend) <= 0){
- //外国算星期 星期天=1; 星期一=2
- if(cstart.get(Calendar.DAY_OF_MONTH)==1 || cstart.get(Calendar.DAY_OF_WEEK)==2)
- {
- ans += 2;
- }
- else ans+=1;
- cstart.add(Calendar.DATE,1); //模拟日历翻一天
- }
- System.out.println(ans);
- }
- }
具体的API方法提取:
DATE | get或set的编号表示该月的日期 |
DAY_OF_MONTH | get/set 本月的日期 |
DAY_OF_WEEK | get/set 一周中的日期 |
add(int field, int amount) | 将指定的日历量增加或减去给定的日历字段 |
compareTo(Calendar ) | 比较时间值Calendar对象 |
get(int field) | 返回给定日历字段的值 |
toString() | 返回此日历的字符串表示形式 |
-
- //时间模拟器
- int y = 2001, m = 1, d = 1; //年,月,日
- int w[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
-
- while( y!= 2021 || m != 12 || d!= 31 )
- {
- //判断是否是闰年
- if(y%400 == 0 || (y%4==0 && y%100!=0)) w[2] = 29;
- else w[2] = 28;
-
- d++;
-
- //日期变更
- if(d > w[m])
- {
- m++;
- d=1;
- }
- if(m>12)
- {
- y++;
- m=1;
- }
- }
对于时间类的题目差不多就到这里了,如果要更加熟练运用的话还需要多多练题测试,以免出现细节上的错误,对于Calendar有需要熟练掌握使用,毕竟快嘛。这一期的总结就到这里啦!大家觉得有用的话也可以收藏,一起继续加油叭!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。