Java 算法课作业1——回文数

这篇博客探讨了一道算法题目,要求找出从公元1年1月1日到给定日期x年y月z日之间的回文日期数量。博主分享了题目要求,输入输出格式,并提供了自己的解题思路,包括如何判断回文数以及优化循环条件。同时,博主也提到从他人代码中学习到的技巧,如简化回文数判断和优化循环结束条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 算法课作业1——回文数

题目要求

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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值