日期问题——蓝桥杯真题Python||动态规划

个人觉得难在有三种情况,是年月日,日年月,日月年,但是题目里写的又是年月日,月日年,日月年。
按第二个情况写出来的又是错的,按示例分析出来是第一种情况。


在这里插入图片描述

题目:日期格式解析与合法性验证

题目描述

给定一个形如 AA/BB/CC 的日期字符串,其中 AABBCC 为两位数字。该字符串可能代表以下三种日期格式之一:

  • 年/月/日(如 02/03/04 → 2002年3月4日)
  • 月/日/年(如 02/03/04 → 2004年2月3日)
  • 日/月/年(如 02/03/04 → 2004年3月2日)

要求输出所有可能的合法日期(范围:1960-01-01 至 2059-12-31),并按时间升序排列。


解题思路

1. 输入拆分与候选组合生成

将输入的三个部分 AABBCC 转换为整数后,生成三种可能的日期组合:

  • (AA, BB, CC) → 年/月/日
  • (CC, AA, BB) → 年/月/日(交换后)
  • (CC, BB, AA) → 年/月/日(另一种交换)
2. 年份处理
  • 两位年份的转换规则:
    • 若数值 ≤ 59,补全为 20xx(如 04 → 2004)
    • 若数值 ≥ 60,补全为 19xx(如 60 → 1960)
3. 日期合法性验证

需满足以下条件:

  • 年份范围:1960 ≤ 年 ≤ 2059
  • 月份范围:1 ≤ 月 ≤ 12
  • 日期范围:不超过当月最大天数(需考虑闰年)
4. 去重与排序

使用集合(set)存储结果以去重,最后转换为列表并排序。


代码实现

import os
import sys

def is_valid(year, month, day):
    # 检查年份范围是否合法
    if year < 1960 or year > 2059:
        return False
    # 检查月份是否合法
    if month < 1 or month > 12:
        return False
    # 初始化各月份最大天数
    month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    # 闰年判断
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
        month_days[1] = 29
    # 检查日期是否超出当月最大值
    if day < 1 or day > month_days[month - 1]:
        return False
    return True

def main():
    input_str = input().strip()
    parts = input_str.split('/')
    x = int(parts[0])
    y = int(parts[1])
    z = int(parts[2])
    
    # 三种可能的日期组合
    candidates = [(x, y, z), (z, x, y), (z, y, x)]
    results = set()
    
    for candidate in candidates:
        year_part, month, day = candidate
        # 补全年份为四位数
        full_year = 1900 + year_part if year_part > 59 else 2000 + year_part
        if is_valid(full_year, month, day):
            # 格式化为标准字符串
            date_str = f"{full_year}-{month:02d}-{day:02d}"
            results.add(date_str)
    
    # 按日期排序并输出
    sorted_dates = sorted(results)
    for date in sorted_dates:
        print(date)

if __name__ == '__main__':
    main()

关键代码解析

1. 闰年判断
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
    month_days[1] = 29
  • 闰年规则:能被4整除但不能被100整除,或能被400整除的年份为闰年,2月有29天。
2. 年份补全逻辑
full_year = 1900 + year_part if year_part > 59 else 2000 + year_part
  • year_part 是两位数的年份部分:
    • >59(如 60 → 1960)
    • ≤59(如 04 → 2004)
3. 日期格式化
f"{full_year}-{month:02d}-{day:02d}"
  • :02d 保证月和日用两位数字表示(不足补零),例如 303

复杂度分析

  • 时间复杂度:O(1)
    仅需处理三种固定组合,所有操作均在常数时间内完成。
  • 空间复杂度:O(1)
    存储结果的空间不超过三个日期字符串。

测试案例

输入 1
02/03/04
输出 1
2002-03-04
2004-02-03
2004-03-02
输入 2
29/02/03
输出 2
2029-02-03

总结

本题的关键在于正确处理多格式的日期组合和严格的合法性验证。通过以下步骤解决:

  1. 生成候选日期组合:覆盖所有可能的格式。
  2. 年份补全与范围检查:确保年份在题目要求的范围内。
  3. 日期合法性验证:包括月份、日期和闰年判断。
  4. 去重与排序:保证输出结果的唯一性和有序性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值