这个题解还是挺适合新手的,知识就是基础的循环 选择 数组
解题思路
从输入得日期开始循环到99999999,一直到输出两个符合的日期
判断回文日期我用的是先把8位数的每一位都存入一个数组中
将数字的每一位分别存入数组中
for (int i = 0; i < 8; i++) {
int t = (int) (Math.pow(10, i));
int t1 = (int) (Math.pow(10, i + 1));
a[i] = j / t % 10;
}
然后让数组的第一位和最后位比较看是否相等遍历玩均相等就是回文数
这个for循环来判断是否是回文数
for (int i = 0; i < 4; i++) {
if (a[i] != a[7 - i]) {
f = 0;
break;
}
f = 1;//是回文数给表示状态的f=1
}
然后是回文数之后接着判断是否是合法日期
public static boolean isdate(int[] a) {
//月份对应的天数
int[] m = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31};
int year = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];//得到年
// 判断是否闰年
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
m[2] = 29;
}
int month = a[4] * 10 + a[5];//得到月
int day = a[6] * 10 + a[7];//得到日
if (month > 12 || month == 0)//如果月不符合12月,返回假
{
return false;
}
// 如果日大于月的天数或等于0为假
if (day > m[month] || day == 0) {
return false;
}
return true;
}
是回文数以及合法日期后判断是否是ABABBABA型回文数
if (f1 == 1 && a[0] == a[2] && a[1] == a[3]) {
for (int z = 7; z >= 0; z--) {//是ABABBABA型就输出数子
System.out.print(a[z]);
}
完整代码
import java.util.Scanner;
public class Lanqiao1 {
public static boolean isdate(int[] a) {
//月份对应的天数
int[] m = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31};
int year = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];//得到年
// 判断是否闰年
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
m[2] = 29;
}
int month = a[4] * 10 + a[5];//得到月
int day = a[6] * 10 + a[7];//得到日
if (month > 12 || month == 0)//如果月不符合12月,返回假
{
return false;
}
// 如果日大于月的天数或等于0为假
if (day > m[month] || day == 0) {
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[8];//创建一个数组用来后续装日期每一位数,并判断是否是回文数
int f = 0;//只有f=0时输出第一个回文数
int f1 = 0;//f1=1时输出AB型回文数
for (int j = n + 1; j <= 99999999; j++) {
if(j%10==0||j%10000/100>12)//这一步很关键 在刚开始循环的时候就排除尾数是0的(尾数是0首位也得是0 不要符合)以及月份(j%10000/100得月份)大于12月的
continue;
// 将数字的每一位分别存入数组中
for (int i = 0; i < 8; i++) {
int t = (int) (Math.pow(10, i));
int t1 = (int) (Math.pow(10, i + 1));
a[i] = j / t % 10;
}
// 这个for循环来判断是否是回文数
for (int i = 0; i < 4; i++) {
if (a[i] != a[7 - i]) {
f = 0;
break;
}
f = 1;//是回文数给表示状态的f=1
}
if (f == 1 && isdate(a))//f==1则这个数是回文数 isdate()判断这个数是不是合法日期
{
if (f1 == 0){
for (int i = 7; i >= 0; i--) {
System.out.print(a[i]);
}
f1 = 1;//输出第一个回文数后令f1=1;
System.out.println();}
//f1==1 判断第一个回文数是否已经输出
// a[0] == a[2] && a[1] == a[3]判断回文数是否是ABABBABA型
if (f1 == 1 && a[0] == a[2] && a[1] == a[3]) {
for (int z = 7; z >= 0; z--) {
System.out.print(a[z]);
}
break;
}
}
}
}
}
本题坑点
1.题干上写的对于所有评测用例, 8999123110000101≤N≤89991231,
但是咱循序肯不能 i<=89991231 因为你输入89991231 得到的结果应该是
90011009
90900909
因此你循环得这样写 for (int j = n + 1; j <= 99999999; j++) {
2. for (int j = n + 1; j <= 99999999; j++) {暴力枚举会超时
你得过滤掉一点数字
if(j%10==0||j%10000/100>12)//这一步很关键 在刚开始循环的时候就排除尾数是0的(尾数是0首位也得是0 不要符合)以及月份(j%10000/100得月份)大于12月的
continue;
如果这个数以0结尾那么它就不可能是回文数(首位数不可能是0)
那只考虑尾数是1~9的速度优化到90%
如果他的表示月份的第四位和第五位不在1~12之间那它必定不是日期
那就只考虑第四位和第五位在1~12的优化了原来的12%
你看加上这两个判断条件
速度就变成了原来的90%*12%=10.8%
相当于快了10倍这样就不会超时了