24:打印月历
总时间限制:
1000ms
内存限制:
65536kB
描述
给定年月,打印当月的月历表。
输入
输入为一行两个整数,第一个整数是年份year(1900 ≤ year ≤ 2099),第二个整数是月份month(1 ≤ month ≤ 12),中间用单个空格隔开。
输出
输出为月历表。月历表第一行为星期表头,如下所示:
Sun Mon Tue Wed Thu Fri Sat
其余各行一次是当月各天的日期,从1日开始到31日(30日或28日)。
日期数字应于星期表头右对齐,即各位数与星期表头相应缩写的最后一个字母对齐。日期中间用空格分隔出空白。
样例输入
2006 5
样例输出
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
提示
闰年判断方法:能被4整除但不能被100整除,或者能被400整除。
1900年1月1日是周一。
题解:
这道题是典型的模拟日期变更的题目。为了节省时间提高效率,可把目标年份的1月1日的星期算出来,然后通过循环模拟,最终算出目标月份的1日的星期。
计算部分在本题还算简单,但重要的是如何输出。
首先输出固定格式,
我们知道日历的开头通常都是有空格的(1日是星期天除外),由此我们可以写循环来输出日历前面的空格。
接下来依次输出每个日期,这里又会有个问题,就是换行的问题,这个问题可以通过声明一个变量判断日历是否打印到行尾,是就换行,不是就输出空格。
还有一点细节需要注意,当日期到最后一天时,是不允许有空格出现的,所以我们应该在最后加一个条件判断,这样程序就完整了。
#include<cstdio>
#include<cstdlib>
int main()
{
int year,month;
scanf("%d %d",&year,&month);
int day=1;
for(int i=1;i<=year-1900;i++)
{
int sum=1900+i-1;
if((sum%4==0&&sum%100!=0)||sum%400==0)
day+=2;
else
day++;
if(day>=8)
day-=7;
}
for(int i=1;i<month;i++)
{
if(i!=2)
{
switch(i)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:day+=31%7;break;
case 4:case 6:case 9:case 11:day+=30%7;break;
}
}
else
{
if((year%4==0&&year%100!=0)||year%400==0)
day+=29%7;
else
day+=28%7;
}
if(day>=8)
day-=7;
}
int count;
if(month!=2)
{
switch(month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:count=31;break;
case 4:case 6:case 9:case 11:count=30;break;
}
}
else
{
if((year%4==0&&year%100!=0)||year%400==0)
count=29;
else
count=28;
}
printf("Sun Mon Tue Wed Thu Fri Sat\n");
for(int i=day==7?0:day;i!=0;i--)
{
printf(" ");
}
int n=day;
for(int i=1;i<=count;i++)
{
if(i<=9)
printf(" %d",i);
else
printf(" %d",i);
if(i==count)
;
else if(n%7==6)
printf("\n");
else
printf(" ");
n++;
}
return 0;
}