# a468 - February 29 ### 題目連結: [a468](https://zerojudge.tw/ShowProblem?problemid=a468) ### 題目解析 * 計算兩個日期之間的閏日有多少天 * 所謂的閏日指的是該年份2月會有29日 * 例如 2012/01/01 ~ 2013/12/31 一共有一個閏日 ### 題目類型 數學/曆法/基礎輸出入 ### 範例測資解讀 * 輸入 * 為一個複合型的測資輸入,第一行為 T 代表測資數量 * 第二行以後,每兩行為一組資料 * 其中第一行代表開始的日期 * 第二行代表結束的日期,且該行的日期絕對不會比第一行早 * 輸出 * 格式化輸出兩個日期之間有多少個閏日 ### 其他注意事項 * 此題的輸入格式與過去的不同,需要處理有空白和逗號的混合字串 ### 程式解析 * 計算兩個日期之間的閏日有幾個,關鍵在於兩個年份之間會碰到幾次閏年.其他非閏年的一年12個月的時間其實都相同 * 但是如果要直接計算兩個日期相當麻煩,因此我們可以逆轉想法: * 閏日差 = 日期2 - 日期1 * 調整為 * 閏日差 = (西元元年~日期2的閏日總數) - (西元元年~日期1的閏日總數) ![](https://i.imgur.com/GlOqCYV.png) * 為什麼是這樣設計呢? 因為計算單一日期的閏日總數比兩個日期的差值來的容易計算 ![](https://i.imgur.com/caiVsQ4.png) 首先處理輸入資料,此題的輸入資料因為有一個, 所以 split 切開後的資料無法直接轉換型態,但我們可以動態調整串列的內容,主要要做兩個處理: 1. 移除逗號 2. 將英文月份轉換為數字 移除逗號的方式將切割後的資料使用 strip() 函式去除 ``` python date1 = input().split() date2 = input().split() # date list example: ['January', '12,', '2012'] date1[1] = date1[1].strip(',') date2[1] = date2[1].strip(',') ``` 將英文月份轉換為數字可以建立一個簡單的對照表 ``` python month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] ``` 處理完輸入資料後,接著就要進行單一日期的閏日計算.需要注意測資的年月日 * 如果開始的年份是閏年, 且日期在 2/29 以前, 閏年+1 * 如果開始的年份是閏年, 且日期在 3/1 以後, 維持原狀 * 如果結束的年份是閏年, 且日期在 2/29 以前, 維持原狀 * 如果結束的年份是閏年, 且日期在 3/1 以後, 閏年+1 ``` python #date1: y1, m1, d1 #date2: y2, m2, d2 if m1>1: y1 +=1 if m2 == 0 or m2 == 1 and d2<29: y2 -=1 ``` 接著利用閏年計算的公式,即可找出該日期的閏日總數 (每4年一閏,100年不閏,每400年閏) ``` python def leap_year(y): value = y//4 -y//100 + y//400 return value ``` 最後我們只要將兩個日期的閏日總數相減,即可解出此題! ### 完整程式碼 (僅提供參考) ``` python=01 month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] def leap_year(y): value = y//4 -y//100 + y//400 return value #start T = int(input()) for i in range(1, T+1): date1 = input().split() date2 = input().split() for m in range(12): if date1[0] == month[m]: date1[0] = m if date2[0] == month[m]: date2[0] = m date1[1] = date1[1].strip(',') date2[1] = date2[1].strip(',') m1, d1, y1 = map(int, date1) m2, d2, y2 = map(int, date2) #2. 計算那個年份是否為閏年 if m1>1: y1 +=1 if m2 == 0 or m2 == 1 and d2<29: y2 -=1 #3. 相差幾個年份的算法? #|------------------------> year1 (開始) #0 4 8 12 16 .... #|-----------------------------------------> year2 (結束) leap_year1 = leap_year(y1-1) leap_year2 = leap_year(y2) print("Case %d: %d" % (i, leap_year2-leap_year1) ) ``` ###### tags: `基礎15題解` `APCS` `ZeroJudge`