解析: 我们知道,回文数就是折半之后前后两两对称的数,所以,我们可以直接通过一些方法来对比前后的数是否相等
方法1:将数转换为字符串,分别取前后索引进行对比(可以用循环,也可以直接写出所有情况,或者利用字符串截取和StringBuilder的反转函数reveser)
方法2:利用取余得到每一位上的数,进而比较,例:
20200202%100 = 02 = 2 可知日期为2号
根据题目的要求,测试实例为10000101≤N≤89991231,也就是输入的日期范围,因为日期要求为8位数,故而我们应该判断的日期范围应为[输入日期,99999999],
又因为是从输入日期开始后的下一个回文日期,故而判断范围的起始应该为输入日期+1,这一步是为了消除当输入日期本身就是一个回文日期从而影响结果的准确性。
利用循环,遍历日期范围,利用上述的两种方式,判断是否为回文日期,在回文日期之后,我们可以再追加一个ABABBABA型回文数的判断,因为已经是回文数了,所以根据前后对称的原则,到这里我们只需要判断[0,2)字符串和[2,4)字符串是否相等即可,如果02和24相等,那么后面也必然是相等的。做完上面这些,我们就可以获取到[输入日期,99999999]之间的所有回文日期和ABABBABA型回文日期了,但是,这里面并不是每一个都符合日期要求,比如,一年不能超过12个月,一个月最多只能有31天,故而,从右往左,1、2位组合的最大数值不能大于31,3,4位组合的最大数不能超过12,(5、6)和(7、8)分别是(3,4)和(1,2)的反序,
例如,(1,2)的取值为:【01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19…31】
对应的(7,8)的取值为(1,2)的反序,及【10,20,30,40,50,60,70,80,90,01,11,21,31,41…13】
(3,4)、(5,6)同理,我们可以利用链表来存储这些数据,当我们获取到一个日期时,先判断它是否是一个合理的日期,如果不是,也就没必要判断它是否是回文日期了。以上就是全部的内容解析了!
总结 :先循环遍历所有可能的日期,再利用日期合法性筛选不合法的日期,对于合法的日期,判断它是否为回文数,如果是,再判断是否为ABABBABA型回文数。
源码如下:
//存放天数的反串
static List<Integer> dayReseveValue = new ArrayList<>();
//存放月份的反串
static List<Integer> MoneyReseveValue = new ArrayList<Integer>();
static {
dayReseveValue.add(1);
dayReseveValue.add(10);
dayReseveValue.add(11);
dayReseveValue.add(20);
dayReseveValue.add(21);
dayReseveValue.add(30);
dayReseveValue.add(40);
dayReseveValue.add(50);
dayReseveValue.add(60);
dayReseveValue.add(70);
dayReseveValue.add(80);
dayReseveValue.add(90);
for(int i=1;i<=31;i++) {
//01对应10,但是01没有0,所以要默认*10
if(i<10)
MoneyReseveValue.add(i*10);
else
MoneyReseveValue.add(Integer.parseInt(revese(i+"")));
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int date = scan.nextInt();//输入日期
boolean firstPalindrome = true;//回文数输出判定条件
for(int i=date+1;i<99999999;i++) {
if(i%100>31||i/100%100>12||!isMonthOk(((int)(i/Math.pow(10, 6))))||!isDayOK(i/10000%100)) {
continue;
}
// if(i%100>31||((int)(i/Math.pow(10, 6)))>31||(i/10000%100)>12||(i/100%100)>12)
// continue;
//判断回文数
//revese((i+"").substring(4,8))) 取4位反转
if((i+"").substring(0,4).equals(revese((i+"").substring(4,8)))) {
//只输出一次回文数,后面的回文都用来判断是否为ABABBABA,一旦都找到,结束循环
//回文和ABABBABA型回文可以同时为一个数
if(firstPalindrome) {
firstPalindrome=!firstPalindrome;
System.out.println(i);
}
if(isABABBABA(i+"")) {
System.out.println(i);
break;
}
}
}
scan.close();
}
//判断年份部分中对应月份部分是否合法
static boolean isMonthOk(int num) {
return MoneyReseveValue.contains(num);
}
//判断月份部分对应天数部分是否合法
static boolean isDayOK(int num) {
return dayReseveValue.contains(num);
}
//判断是否为ABABBABA型回文数
static boolean isABABBABA(String date) {
//因为判断的都是回文数,所以abab型只需要判断02和04这个区间
return date.substring(0, 2).equals(date.substring(2,4));
}
//将形参字符串反转并返回
static String revese(String str) {
return new StringBuilder(str).reverse().toString();
}