日期: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;
}
沒有留言:
張貼留言