题解:学而思编程 最年长的人

【题目来源】

学而思编程:最年长的人

【题目描述】

小猴班上有 \(n\) 名同学,小猴作为班长知道班上每名同学的出生日期。现在小猴想要知道班上最大年龄的同学的出生日期是多少,请你帮助小猴完成这个任务。

【输入】

第一行一个正整数 \(n\)

第二行到第 \(n+1\) 行,每行三个整数 \(a,b,c\),表示每位同学的出生日期(即 \(a\)\(b\)\(c\) 日出生)。

【输出】

一行三个整数 \(y,m,d\),表示年龄最大同学的出生日期,\(m,d\) 如果是一位数时需要有前导 \(0\)

【输入样例】

3
2008 01 02
2010 10 20
2010 11 11

【输出样例】

2008 01 02

【核心思想】

  1. 问题分析:给定 \(n\) 名同学的出生日期,求年龄最大(即出生日期最早)的同学的出生日期。这是一个日期比较 + 贪心更新问题,关键在于按年、月、日的优先级依次比较,找到最早的日期。

  2. 算法选择

    • 初始化最新日期:将当前最优日期设为一个较晚的日期(如 \(2021\)\(12\)\(31\) 日)
    • 逐日期比较:按年、月、日的优先级依次比较,更新最早日期
  3. 关键步骤

    • 初始化
      • 读取 \(n\)
      • y = 2021, m = 12, d = 31:初始化为较晚日期
    • 逐日期比较(遍历 \(i\)\(1\)\(n\)):
      • 读取 \(a, b, c\)(年、月、日)
      • \(a > y\)continue(当前日期更晚,不更新)
      • 否则若 \(a < y\):更新 y = a, m = b, d = c(当前日期更早)
      • 否则(年份相同):
        • \(b > m\)continue(月份更晚,不更新)
        • 否则若 \(b < m\):更新 m = b, d = c(月份更早)
        • 否则(年月相同):d = min(d, c)(取更早的日)
    • 格式化输出printf("%d %02d %02d", y, m, d):月份和日期保持两位,不足补前导零
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n)\),线性遍历 \(n\) 个日期
    • 空间复杂度:\(O(1)\),仅需存储当前最优日期
  5. 日期比较的核心思想

    • 字典序比较:日期按年、月、日优先级依次比较,与字符串字典序比较同理,先比高位再比低位
    • 贪心更新:遇到更早的日期立即更新,保证遍历结束后得到全局最早日期
    • 初始化策略:初始化为一个足够晚的日期(晚于所有可能的输入),确保第一个日期必然更新
    • 格式化输出%02d 确保月份和日期为两位数,不足时自动补前导零
    • 适用于"多关键字比较 + 极值查找"类问题,按优先级逐层比较是标准方法

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n;  // 输入日期的数量

int main()
{
    cin >> n;  // 输入日期数量

    // 初始化最新日期为2021年12月31日
    int y = 2021;  // 年份
    int m = 12;    // 月份
    int d = 31;    // 日期

    // 处理每个输入的日期
    for (int i = 1; i <= n; i++)
    {
        int a, b, c;  // 当前输入的日期:a=年, b=月, c=日
        cin >> a >> b >> c;

        // 比较逻辑:寻找最早的日期
        if (a > y)  // 如果当前年份比最新日期晚
        {
            continue;  // 跳过,不更新
        }
        else if (a < y)  // 如果当前年份比最新日期早
        {
            y = a;  // 更新年份
            m = b;  // 更新月份
            d = c;  // 更新日期
        }
        else  // 年份相同
        {
            if (b > m)  // 如果当前月份比最新日期晚
            {
                continue;  // 跳过,不更新
            }
            else if (b < m)  // 如果当前月份比最新日期早
            {
                m = b;  // 更新月份
                d = c;  // 更新日期
            }
            else  // 年份和月份都相同
            {
                d = min(d, c);  // 取更早的日期
            }
        }
    }

    // 输出最早日期,月份和日期用两位数字表示
    printf("%d %02d %02d\n", y, m, d);

    return 0;  // 程序正常结束
}

【运行结果】

3
2008 01 02
2010 10 20
2010 11 11
2008 01 02
posted @ 2026-07-05 14:45  团爸讲算法  阅读(3)  评论(0)    收藏  举报