日期類問題
日期類問題
@(演算法)
日期類問題中最基本的問題——求兩個日期間的天數差。
解決這類區間問題有一個統一的思想——把原區間問題統一到起點確定的區間問題上去 。
日期類問題有一個特別需要注意的要點——閏年
閏年的判斷規則:當年數不能被100整除時若能被4整除,或者其能被400整除時也是閏年。
用邏輯表示式為:Year%100!=0 && Year%4==0 || Year%400==0
例題
題目描述
We now use the Gregorian style of dating in Russia. The leap years are years with number divisible by 4 but not divisible by 100, or divisible by 400.For example, years 2004, 2180 and 2400 are leap. Years 2004, 2181 and 2300 are not leap.
輸入
There is one single line contains the day number d, month name M and year number y(1000≤y≤3000). The month name is the corresponding English name starting from the capital letter.
輸出
Output a single line with the English name of the day of week corresponding to the date, starting from the capital letter. All other letters must be in lower case.
樣例輸入
9 October 2001
樣例輸入
Tuesday
程式碼塊
// task.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> #include <cstdio> #include <cstdlib> #define ISYEAR(x) x%100!=0 && x%4==0 || x%400==0?1:0 //判斷是否是閏年 using namespace std; //每月的天數 int dayOfMonth[13][2] = { 0,0, 31,31, 28,29, 31,31, 30,30, 31,31, 30,30, 31,31, 31,31, 30,30, 31,31, 30,30, 31,31 }; struct Date { int Year; int Month; int Day; void nextDay() {//計算下一天的日期 Day++; if (Day > dayOfMonth[Month][ISYEAR(Year)]) { Day = 1; Month++; if (Month > 12) { Year++; Month = 1; } } } }; //每個月的名稱 char monthName[13][20] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; //每天的名稱 char weekName[7][20] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; int buf[3001][13][32]; int main() { Date date; int t = 0; date.Year = 0; date.Month = 1; date.Day = 1; while (date.Year != 3001) { buf[date.Year][date.Month][date.Day] = t; date.nextDay(); t++; } int d, m, y; char s[20]; while (scanf("%d%s%d", &d, s, &y) != EOF) { for (m = 1; m <= 12; m++) { if (strcmp(s, monthName[m])==0) {//將輸入字串與月名比較得出月數 break; } } int days = buf[y][m][d] - buf[2019][2][26]; days += 2;//今天是2019.02.26,星期二,故 days+2 puts(weekName[(days % 7 + 7) % 7]);//用7對其取模,並且保證其為非負數 } return 0; }
總結
1.善用結構體
2.判斷閏年 :#define ISYEAR(x) x%100!=0 && x%4==0 || x%400==0?1:0
3.迴圈nextDay()
,將日期轉換成int
整型,把原區間問題統一到起點確定的區間問題上去。
int days = buf[y][m][d] - buf[2019][2][26]; days += 2;//今天是2019.02.26,星期二,故 days+2 puts(weekName[(days % 7 + 7) % 7]); //用7對其取模,並且保證其為非負數
關鍵程式碼!int days = buf[y][m][d] - buf[2019][2][26]
可能為負數;
days % 7 + 7) % 7
用7對其取模,保證其為非負數。
參考資料:計算機考研——機試指南[電子工業出版社]