題目:判斷對應日期是星期幾。其中涉及閏年計算,閏年按歷史上的實際情況計算:
1.1752年9月2日之前,使用四年一閏的方式;
2.1752年9月14日之後,使用現在的閏年計算方式(四年一閏,百年不閏,四百年閏);
3.1752年9月2日的後一天為752年9月14日(缺少的11天補足之前閏年的遺漏);
分析:模擬。按照上面規則計算即可。
因為1752年9月14之後的時間有個跳躍,可以將752年9月2日之前的日期+11進行統一;
(當然也可以將後面的-11進行統一);
說明:1年1月1日,不知道是週幾,嘗試和數據對比一下進行校準。
#include <stdio.h>
#include <stdlib.h>
char week_name[][10] = {
"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
};
char month_name[][10] = {
"","January","February","March","April","May","June","July",
"August","September","October","November","December"
};
int is_leap(int year)
{
if (year <= 1752) {
return (year%4 == 0);
}else {
return (year%4 == 0 && year%100 != 0) || (year%400 == 0);
}
}
int year_days(int year)
{
return 365 + is_leap(year);
}
int month_days(int year, int month)
{
if (month == 2) {
return 28 + is_leap(year);
}else if (month < 8 && month%2 == 1 || month > 7 && month%2 == 0) {
return 31;
}else {
return 30;
}
}
int is_valid(int year, int month, int day)
{
if (month < 1 || month > 12) {
return false;
}else if (day < 1 || day > month_days(year, month)) {
return false;
}else if (year == 1752 && month == 9 && day > 2 && day < 14) {
return false;
}else {
return true;
}
}
int main()
{
int month, day, year;
while (~scanf("%d%d%d", &month, &day, &year)) {
if (year == 0 && month == 0 && day == 0) break;
if (!is_valid(year, month, day)) {
printf("%d/%d/%d is an invalid date.\n",month,day,year);
}else {
int sum = 1; // test fit start day
for (int i = 1; i < year; ++ i) {
sum += year_days(i);
}
for (int i = 1; i < month; ++ i) {
sum += month_days(year, i);
}
sum += day;
if (year < 1752 || year == 1752 && month < 9 ||
year == 1752 && month == 9 && day < 3) {
sum += 11; // add 9.14 - 9.3
}
printf("%s %d, %d is a %s\n",
month_name[month], day, year, week_name[sum%7]);
}
}
return 0;
}