1 条题解

  • 0
    @ 2026-1-16 21:29:49

    本题题解,只需根据题意算出年龄,再代入公式即可。需要特别注意闰年。

    本题完整代码:

    #include <iostream>
    #include <cmath>
    #include <iomanip>
    #include <ctime>
    
    // 判断闰年
    bool isLeap(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }
    
    // 获取某年某月的天数
    int daysInMonth(int year, int month) {
        static const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (month == 2 && isLeap(year)) {
            return 29;
        }
        return days[month - 1];
    }
    
    // 计算精确年龄(以年为单位)
    double calculateAge(int birthYear, int birthMonth, int birthDay,
                        int currentYear, int currentMonth, int currentDay) {
        // 先按年份粗略计算
        int ageYears = currentYear - birthYear;
    
        // 如果还没过生日,减一岁
        if (currentMonth < birthMonth ||
            (currentMonth == birthMonth && currentDay < birthDay)) {
            ageYears--;
        }
    
        // 如果年龄已经是负数,说明出生日期在未来
        if (ageYears < 0) return -1.0;
    
        // 计算生日到今天的天数(今年已过的天数)
        int daysSinceBirthday = 0;
        if (currentMonth > birthMonth ||
            (currentMonth == birthMonth && currentDay >= birthDay)) {
            // 生日已过,从生日到今天
            int y = currentYear;
            for (int m = birthMonth; m < currentMonth; ++m) {
                daysSinceBirthday += daysInMonth(y, m);
            }
            daysSinceBirthday += (currentDay - birthDay);
        } else {
            // 生日未过,从生日到年底,再加今年已过天数(这种情况不会进入,因已减1岁)
            // 实际上我们只在生日已过时才加小数部分
            daysSinceBirthday = 0;
        }
    
        // 计算今年生日到明年生日的总天数(用于小数部分)
        int daysInYearAfterBirthday = 0;
        int y = currentYear;
        for (int m = birthMonth; m <= 12; ++m) {
            daysInYearAfterBirthday += daysInMonth(y, m);
        }
        for (int m = 1; m < birthMonth; ++m) {
            daysInYearAfterBirthday += daysInMonth(y + 1, m);
        }
    
        double fractional = static_cast<double>(daysSinceBirthday) / daysInYearAfterBirthday;
        return static_cast<double>(ageYears) + fractional;
    }
    
    int main() {
        int birthYear, birthMonth, birthDay;
        std::cin >> birthYear >> birthMonth >> birthDay;
    
        // 获取当前本地时间
        std::time_t now = std::time(nullptr);
        std::tm* localTime = std::localtime(&now);
        int currentYear = localTime->tm_year + 1900;
        int currentMonth = localTime->tm_mon + 1; // tm_mon: 0-11
        int currentDay = localTime->tm_mday;
    
        // 验证输入合理性(简单检查)
        if (birthMonth < 1 || birthMonth > 12 ||
            birthDay < 1 || birthDay > daysInMonth(birthYear, birthMonth)) {
            // 输入无效,保守输出 0.00%
            std::cout << "0.00%" << std::endl;
            return 0;
        }
    
        // 计算精确年龄
        double age = calculateAge(birthYear, birthMonth, birthDay,
                                  currentYear, currentMonth, currentDay);
    
        if (age < 0) {
            std::cout << "0.00%" << std::endl;
            return 0;
        }
    
        const double START_AGE = 3.0;
        const double MAX_LIFESPAN = 100.0;
    
        double percentage;
        if (age <= START_AGE) {
            percentage = 0.0;
        } else if (age >= MAX_LIFESPAN) {
            percentage = 100.0;
        } else {
            double y = std::log(age / START_AGE) / std::log(MAX_LIFESPAN / START_AGE);
            percentage = y * 100.0;
            // 限制范围
            if (percentage < 0) percentage = 0.0;
            if (percentage > 100) percentage = 100.0;
        }
    
        std::cout << std::fixed << std::setprecision(2) << percentage << "%" << std::endl;
    
        return 0;
    }
    

    信息

    ID
    5
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者