题目要求
1.题目描述
2018年10月2日是一个神奇的日子,因为将数字连起来就变成了2018102,2018102是一个正读倒读都一样的整数。
那么,问题来了,从公元1年1月1日到x年y月z日,有多少个这样神奇的日子?
注意:对于任意一天,a年b月c日中的a, b, c
这三个数都不能有前导零,且要求是合法的日子。别忘记考虑闰年。
2.输入数据
三个整数 x, y, z (1≤x≤2018, 1≤y≤12, 1≤z≤31)
表示x年y月z日,保证日期合法。
3.输出数据
回文日期的个数(一个整数)。
4.样例输入
1000 1 1
5.样例输出
1487
代码
import java.util.Scanner;
public class Hw1 {
// 判断是否是回文数
public boolean isParlindrome(int year, int month, int day) {
String y = String.valueOf(year);
String m = String.valueOf(month);
String d = String.valueOf(day);
String former = y + m + d; // 要判断的数列
String latter = "";
for (int i = former.length() - 1; i >= 0; i--) {
latter += former.charAt(i);
}
if (former.equals(latter)) {
return true;
} else {
return false;
}
}
// 判断是否是闰年
public boolean isLeepYear(int year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return true;
else
return false;
}
public static void main(String[] args) {
Hw1 hw1 = new Hw1();
int[] daysOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // 记录一月有多少天
int count = 0; // 出现回文数的次数
Scanner scanner = new java.util.Scanner(System.in);
int year, month, day; // 记录输入日期
year = scanner.nextInt(); // 控制台读入
month = scanner.nextInt();
day = scanner.nextInt();
//year之前的年 月份个数为12
for (int y = 1; y <= year; y++) {
int monthLimit=12; //记录一年有几个月份
boolean isLeepYear = hw1.isLeepYear(y);
if (isLeepYear) {
daysOfMonth[1] = 29; // 将2月改为29天
}
//year这一年 月份个数为month
if (y==year) {
monthLimit=month;
}
for (int m = 1; m <= monthLimit; m++) {
int dayLimit=daysOfMonth[m-1]; //记录一个月有几天
if (y==year&&m==month) {
dayLimit=day;
}
for (int d = 1; d <= dayLimit; d++) {
if (hw1.isParlindrome(y, m, d))
count++;
}
}
// 如果是闰年 再将2月天数改回来
if (isLeepYear) {
daysOfMonth[1] = 28;
}
}
System.out.println(count);
}
}
总结
这道题看了感觉自己实现的方法还是太笨,看了一下学校OJ上得分较高的同学,发现有以下值得学习的地方:
1.判断是否是回文数
判断只需要判断前一半和后一半是否相同即可,无需将全部字符倒序再比较是否相等。c++程序:
int judge(string s) {
int len = s.length();
for (int i = 0; i < len / 2; i++) {
if (s[i] != s[len-i-1]) {
return 0;
}
}
return 1;
}
2.判断是否到达当前年当前月
在没有到达当前年月时,每年有12个月,每月有相应的30或31或29或28天,到达当前年月时,需要即时停止。无需通过monthLimit和dayLimit来控制循环次数,只需在for循环中适当break即可。c++程序:
for (int j = 1; j <= 12; j++) {
if (i == x && j > y) break;
for (int k = 1; k <= m[j]; k++) {
if (i == x && j == y && k > z) break;
stringstream stmp;
stmp << i << j << k;
string s = stmp.str();
ans += judge(s);
}
}