/*
打印出任意输入年的日历:
算法分析与设计:
1)(采用“三天打鱼两天晒网”思路)1990.1.1为周一,则可以计算出输入年的首日到1990.1.1的天数n,
由n%7的余数可得:若余数为0,则与1990.1.1同为周一,否则递推。
2)打印方式:周日-->周六。
3)闰年的方法可以用伪语句描述如下:如果 ((年能被4除尽且不能被100除尽)或能被400除尽)
则该年是闰年;否则不是闰年。
*/
//头文件区
#include <iostream>
#include <iomanip>
using namespace std;
//定义结构体类型
typedef struct DATE
{
int year;
int month;
int day;
}date;
//全局变量区
int days_table[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, //平年每月平均天数365
{0,31,29,31,30,31,30,31,31,30,31,30,31}}; //闰年每月平均天数366
//函数声明区
int Days(date para);
void Output(int year,int month,int begin);
//主函数区
int main()
{
int appointYear;
int totalDays=0; //1990.1.1到指定日期的总天数,初始化为0
cout<<"Please input your appointed year (After 1990):";
cin>>appointYear; //输入指定年份
date temp; //循环指定日期前每年的最后一天
temp.month=12;
temp.day=31;
for(int year=1990;year<=appointYear-1;year++) //计算出1990.1.1到指定日期前一年最后一天的天数
{
temp.year=year;
totalDays+=Days(temp);
}
int k=totalDays%7;
Output(appointYear,1,k+1);
return 0;
}
//某年某月某日到该年1月1日的总天数
int Days(date para)
{
int i,days=0;
int flag=((para.year%4==0&¶.year%100!=0)||para.year%400==0); //flag==0则为平年,否则闰年
for(i=0;i<para.month;i++)
days+=days_table[flag][i];
for(i=0;i<para.day;i++)
days++;
return days;
}
//输出某年日历
void Output(int year,int month,int firstDay)
{
int flag=((year%4==0&&year%100!=0)||year%400==0); //flag==0则为平年,否则闰年
cout<<" "<<"1月"<<endl;
cout<<setw(4)<<"日"<<setw(4)<<"一"<<setw(4)<<"二"<<setw(4)<<"三"<<setw(4)<<"四"<<setw(4)<<"五"<<setw(4)<<"六"<<endl;
if(firstDay!=7) //firstDay为每个月1号的星期号,若该年1月1日为周末,则不需输出空格
for(int i=1;i<=firstDay;i++) //否则按照日历输出格式可知,该年1.1为周几则在首行输出几个空格
cout<<setw(4)<<" ";
for(;month<=12;month++)
{
int n=days_table[flag][month]; //第month月的天数
for(int i=1;i<=n;i++)
{
cout<<setw(4)<<i;
if((i+firstDay)%7==0)
cout<<endl;
}
firstDay=(n+firstDay)%7; //firstDay:下个月1号的星期号,
for(i=1;i<=7;i++) //由输出格式可知,第个月输完,输第i+1个月时,相当于继续输出7个空格(换行)
{
cout<<setw(4)<<" ";
if((i+firstDay)%7==0)
{
cout<<endl<<endl;
if(month!=12)
{
cout<<" "<<month+1<<"月"<<endl;
cout<<setw(4)<<"日"<<setw(4)<<"一"<<setw(4)<<"二"<<setw(4)<<"三"<<setw(4)<<"四"<<setw(4)<<"五"<<setw(4)<<"六"<<endl;
}
}
}
}
}