熱門文章

2026年1月2日 星期五

ZeroJudge 解題筆記:a468. 12439 - February 29

作者:王一哲
日期:2026年1月2日


ZeroJudge 題目連結:a468. 12439 - February 29

解題想法


先自訂 3 個函式,分別為用來檢查指定年份是否為閏年的 is_leap,計算指定年份到西元 0 年的閏年數量的 leaps_before,計算兩個年份之間的閏年數量的 count_leap_years。讀取日期之後,將日期的年、月、日轉成整數。如果起始年在2月29日之後,則不計入該年。如果結束年在2月29日之前,則不計入該年。將調整後的起始年、結束年代入 count_leap_years 計算答案。

Python 程式碼


使用時間約為 24 ms,記憶體約為 3.4 MB,通過測試。
def is_leap(year):  # 判斷輸入的年份是否為閏年
    if year % 400 == 0: return True  # 可以被 400 整除,是閏年
    if year % 100 == 0: return False  # 可以被 100 整除但不能被 400 整除,是平年
    if year % 4 == 0: return True  # 可以被 4 整除但不能被 100 整除,是閏年
    return False  # 其它狀況,是平年

def leaps_before(year):  # 計算指定年份到西元 0 年的閏年數量
    return year//4 - year//100 + year//400

def count_leap_years(start_year, end_year):  # 計算兩個年份之間的閏年數量,包含兩端的年份
    return leaps_before(end_year) - leaps_before(start_year - 1)

""" 主要的解題過程 """
month_map = {"January": 1, "February": 2, "March": 3, "April": 4, "May": 5, "June": 6,
             "July": 7, "August": 8, "September": 9, "October": 10, "November": 11, "December": 12}
T = int(input())  # T 筆測資
for t in range(1, T+1):  # 執行 T 次
    ### 處理起始日期 ###
    date1 = list(input().split())  # 起始日期
    month1 = month_map[date1[0]]  # 起始月份
    day1 = int(date1[1][:-1])  # 起始日,刪除最後的逗號
    year1 = int(date1[2])  # 起始年份
    ### 處理結束日期 ###
    date2 = list(input().split())  # 結束日期
    month2 = month_map[date2[0]]  # 結束月份
    day2 = int(date2[1][:-1])  # 結束日,刪除最後的逗號
    year2 = int(date2[2])  # 結束年份
    ### 調整起始年份和結束年份 ###
    start_year = year1
    end_year = year2
    if is_leap(year1):  # 如果起始年在2月29日之後,則不計入該年
        if month1 > 2 or (month1 == 2 and day1 > 29):
            start_year += 1
    if is_leap(year2):  # 如果結束年在2月29日之前,則不計入該年
        if month2 < 2 or (month2 == 2 and day2 < 29):
            end_year -= 1
    ### 計算閏年數量 ###
    if start_year > end_year:  # 題目保證結束日期在起始日期之後,基本上不會發生
        ans = 0
    else:
        ans = count_leap_years(start_year, end_year)
    print(f"Case {t:d}: {ans:d}")


C++ 程式碼


使用時間約為 3 ms,記憶體約為 348 kB,通過測試。
#include <iostream>
#include <string>
#include <map>
using namespace std;

bool is_leap(int year) {
    if (year%400 == 0) return true;
    if (year%100 == 0) return false;
    if (year%4 == 0) return true;
    return false;
}

int leaps_before(int year) {
    return year/4 - year/100 + year/400;
}

int count_leap_years(int start_year, int end_year) {
    return leaps_before(end_year) - leaps_before(start_year - 1);
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    map<string, int> month_map = 
        {{"January", 1}, {"February", 2}, {"March", 3}, {"April", 4},
         {"May", 5}, {"June", 6}, {"July", 7}, {"August", 8}, 
         {"September", 9}, {"October", 10}, {"November", 11}, {"December", 12}};
    int T; cin >> T;
    for(int t=1; t<=T; t++) {
        /* 讀取起始、結束日期 */ 
        string ms, ds, ys;
        cin >> ms >> ds >> ys;
        ds.pop_back();
        int month1 = month_map[ms], date1 = stoi(ds) , year1 = stoi(ys);
        cin >> ms >> ds >> ys;
        ds.pop_back();
        int month2 = month_map[ms], date2 = stoi(ds) , year2 = stoi(ys);
        /* 調整起始、結束年份 */
        int start_year = year1, end_year = year2;
        if (is_leap(start_year)) {
            if (month1 > 2 || (month1 == 2 && date1 > 29)) {
                start_year++;
            }
        }
        if (is_leap(end_year)) {
            if (month2 < 2 || (month2 == 2 && date2 < 29)) {
                end_year--;
            }
        }
        /* 計算閏年數量 */
        int ans = 0;
        if (start_year <= end_year) {
            ans = count_leap_years(start_year, end_year);
        }
        cout << "Case " << t << ": " << ans << "\n";
    }
    return 0;
}


沒有留言:

張貼留言