一、题目
输入一个年份,以日历的格式打印这一年的所有天数,需要正确的表示每一天是周几。
二、算法
以公元1年1月1日作为万年历的起始日期,公元1年1月1日是周一,所以算法的核心就是就算某一天距离起始日期的天数差,然后根据天数差取模就能得到周几。
拿到输入的年份后,循环打印每个月的日历表格,每个月都计算出这个月第一条距离万年历其实日期的天数差,便能得到当月第一天是周几,然后根据当月的总天数,便能打印出当月的日历表。
三、代码
cpp
#define _CRT_SECURE_NO_WARNINGS 1
// 起始日期:公元1年1月1日,周一
#include <iostream>
#include <vector>
using namespace std;
vector<int> g_monthDays = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
bool LeapYear(int year)
{
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return true;
return false;
}
int GetMonthDays(int year, int month)
{
if (LeapYear(year) && month == 2)
return 29;
return g_monthDays[month - 1];
}
int GetYearDays(int year)
{
if (LeapYear(year))
return 366;
return 365;
}
int GetDays(int year, int month, int day)
{
int sum = 0;
for (int i = 1; i < year; ++i)
{
sum += GetYearDays(i);
}
for (int i = 1; i < month; ++i)
{
sum += GetMonthDays(year, i);
}
sum += day;
return sum;
}
void PrintMonth(int year, int month)
{
printf("|-------------- %d 年 %02d 月 -------------|\n", year, month);
cout << "|------------------------------------------|" << endl;
cout << "| 周日 " << " 周一 " << " 周二 " << " 周三 " << " 周四 " << " 周五 " << " 周六 " << "|" << endl;
int monthDays = GetMonthDays(year, month);
int firstDays = GetDays(year, month, 1);
int weekday = firstDays % 7;
cout << "|";
for (int i = 0; i < weekday; ++i)
cout << " ";
for (int i = 1; i <= monthDays; ++i)
{
printf(" %02d ", i);
weekday = (weekday + 1) % 7;
if (weekday == 0)
cout << "|" << endl << "|";
}
if (weekday != 0)
{
for (int i = 0; i < 7 - weekday; ++i)
cout << " ";
cout << "|" << endl << "|";
}
cout << "------------------------------------------|" << endl;
cout << endl << endl;
}
int main()
{
cout << "请输入年份:";
int year;
cin >> year;
for (int i = 1; i <= 12; ++i)
{
PrintMonth(year, i);
}
return 0;
}
四、测试
共12个月,截取部分月份。