回文日期 (蓝桥云) JAVA

Posted Narnat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回文日期 (蓝桥云) JAVA相关的知识,希望对你有一定的参考价值。

目录

题目描述:

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd”
的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。

有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即
2021 年 12 月 2 日。

也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100
年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算
“千年两遇”。

给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。

输入描述:

输入包含一个八位整数 N,表示日期。

对于所有评测用例,
10000101 ≤ 89991231
N 是一个合法日期的 8 位数表示。

输出描述:

输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。

输入输出样例:

输入

20200202

输出

20211202
21211212


统领:

第一次参加蓝桥杯,所以今天才知道蓝桥杯采用oi机制,即提交后没有任何反馈,这给我的冲击很大,因为我平常写完代码,第一时间是去平台测试,根据平台反馈,找错误原因,而蓝桥杯的赛制,直接让我的这个习惯成为了最大破绽。失去了通过平台找错因的手段,让我备受打击,抱着从头再来的想法。我在蓝桥云找了一道适合我水平的题目,试试一遍能得多少分。
好在这一次侥幸能够全部AC给我带来了一丝希望,以下是通过题目总结我的心得。


本题完整代码:

import java.util.*;
public class Main 
   public static  int month[] = 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31;
   public static void main(String[] args) 
	   Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
       int yy = n / 10000;
       //System.out.println(yy);
       while(true) 
    	   if(check(yy)) 
    		   StringBuffer s = new StringBuffer(String.valueOf(yy));
    		   String s1 = String.valueOf(yy);
    		   s1 = s1 + s.reverse();
    		   if(Integer.parseInt(s1) > n) 
    		     System.out.println(s1);
    		     break;
    		   
    	   
    	   yy  = yy + 1;
       
       int YY = n / 1000000;
       while(true) 
    	   if(check_y(YY)) 
    		   StringBuffer s2 = new StringBuffer(String.valueOf(YY * 100 + YY));
    		   String s3 = String.valueOf(YY * 100 + YY) + s2.reverse();
    		   if(Integer.parseInt(s3) > n) 
    		     System.out.print(s3);
    		     break;
    		   
    	   
    	   YY = YY + 1;
       
   
   public static boolean check_y(int m) 
	   int yy = m * 100 + m;
	   if(yy % 4 == 0 && yy % 100 != 0 || yy % 400 == 0) 
		   month[2] = 29;
	   
	   else month[2] = 28;
	   StringBuffer s = new StringBuffer(String.valueOf(yy));
	   String s1 = "" + s.reverse();
	   int mm = Integer.parseInt(s1.substring(0, 2));
	   int dd = Integer.parseInt(s1.substring(2, 4));
	   //System.out.println(month[2]);
	   if(mm <= 0 || mm > 12) return false;
	   if(month[mm] < dd) return false;
	   return true;
   
   public static boolean check(int n) 
	   int yy = n;
	   if(yy % 4 == 0 && yy % 100 != 0 || yy % 400 == 0) 
		   month[2] = 29;
	   
	   StringBuffer s = new StringBuffer(String.valueOf(yy));
	   String s1 = "" + s.reverse();
	   int mm = Integer.parseInt(s1.substring(0, 2));
	   int dd = Integer.parseInt(s1.substring(2, 4));
	   //System.out.println(month[2]);
	   if(mm <= 0 || mm > 12) return false;
	   if(month[mm] < dd) return false;
	   return true;
   


心得:

蓝桥杯是提交没有反馈的,所以我们得细心细心再细心,不要图快,急着把做后面的题。我导师跟我说一个大哥,去年参赛国二,卷了一年再考蓝桥杯只得了省三。问题不在于他题不会,他是所有题都做了。可想而知,他做的题可能只能通过题目给的样例,而样例又不算分数。所以为了能稳定发挥吧,我对自己的建议是:

1.反复斟酌题目要求:

如果你有一道题是会做的,程序也写出来了,那就要务必保证其能对尽可能多的测试点,题目一定要多读几遍,就拿上述题目来举例子,题目要求输出该日期之后的下一个回文日期,假若你没注意到这一点,那么当N = 20201221时,你的程序输出的可能就是20200202这个输出显然不是正确答案

2.小心谨慎步步为营,多反问:

首先我们应该问自己所有的八位回文数字串都行么?

显然回文日期的月份和天数都得合法才行,即月份应在[0, 12], 天数应该在当月的范围内

再思考到当月的天数范围,我们就意识到了,还得判断这个年是闰年还是平年,这样二月的天数范围我们就明确了

考虑到上述问题后,我们的正确率就提高了,然后就是构思去实现一个check函数判断我们的回文日期是否合法:

public static boolean check(int n) 
	   int yy = n;
	   if(yy % 4 == 0 && yy % 100 != 0 || yy % 400 == 0) 
		   month[2] = 29;
	   
	   StringBuffer s = new StringBuffer(String.valueOf(yy));
	   String s1 = "" + s.reverse();
	   int mm = Integer.parseInt(s1.substring(0, 2));
	   int dd = Integer.parseInt(s1.substring(2, 4));
	   //System.out.println(month[2]);
	   if(mm <= 0 || mm > 12) return false;
	   if(month[mm] < dd) return false;
	   return true;
   

写完check后我们不要急着走,我们应该及时检查这个check函数是否正确,多想几个样例测试一下,确保无误后再继续进行。这样如果整个代码出现问题,至少我们能排除check代码的问题,这就是步步为营。

3.调节代码之间的关系:

那本题为例输出有两个一个是回文日期,一个是ABABBABA型回文,这里就存在一个问题,如果前者输出回文日期,判断的年份刚好是闰年,我们修改了month[2] = 29而下一个这个ABABBABA型日期刚好是平年,这里就容易出问题了。

所以为了解决这个问题,实现ABABBABA型的代码就需要调整了。

 if(yy % 4 == 0 && yy % 100 != 0 || yy % 400 == 0) 
		   month[2] = 29;
	   
	   else month[2] = 28;

如上图我添加了一个else语句,这样代码的正确率又会提高。


总结:

要想用代码去实现一道题目,我们需要把这其中很难多问题分块解决,并用代码去解决。个人亲身体会,去解决这些块问题,要比分析边界要花费的时间更多。所以如果我们写出代码后直接潦草提交,就有可能会因为其中的细节没考虑到而功亏一篑。既然我们已经投入了这么多时间去用编程解决这道题,那么为何不愿多花点时间找出可能的边界,得到更多的分数?显然有时候是我太贪心了,分不清西瓜和芝麻。

想想也是没必要抱怨,能够自己排除bug,分析可能的错因,写出优质代码,让用户有更好的体验。何尝不是一个合格程序员该具备的?😄

利用余下的时间我会继续依靠采用这种一遍过的模式做题,适应oi赛制。

Java蓝桥杯--基础练习 回文数

关键词:

循环 判断 回文数

题目:

解决方法:

 1 package com.algorithm.java.blueBirdge;
 2 
 3 //import java.util.Scanner;
 4 
 5 public class Palindrome {
 6     public static void main(String[] args){
 7 
 8         for(int i=1000;i<=9999;i++){
 9             if(i%10==i/1000 && ( ((i%100)/10)==((i/100)%10))){
10                 System.out.println(i);
11             }
12         }
13     }
14 
15 }

 

以上是关于回文日期 (蓝桥云) JAVA的主要内容,如果未能解决你的问题,请参考以下文章

小学生蓝桥杯Python闯关 | 回文日期

java 蓝桥杯 算法基础 回文串

[蓝桥杯Python]算法练习算法基础算法训练算法模板(持续更新)

蓝桥杯选拔赛真题24python回文数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

蓝桥杯选拔赛真题34python回文数升级 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

蓝桥杯选拔赛真题34python回文数升级 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析