【问题描述】给定年份Y和月份M,输出格式化的月历(利用Zeller公式)
【输入形式】输入两个整数Y和M,之间用一个空格隔开,1600<=Y<=2100,1<=M<=12
【输出形式】如图所示,为了实现此图,做出如下的规定
-
第一行为:"Sun Mon Tur Wed Thu Fri Sat \n"
-
第二行开头不填数字的地方,使用6个空格填充,即:" "
-
有数字的地方,输出格式为"%2d ",后面使用4个空格
-
每一行最后的4个空格是存在的
-
最后一行的回车可加可不加
【样例输入】2021 10
【样例输出】
Sun Mon Tur 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
【样例说明】(这里对不齐是因为用的不是等宽字体)2021.10.1是星期五,共有31天
注意:如2021.2.1是星期一,共有28天
思路:本题要求输入年份与月份能打印出月历,首先是利用zeller公式,给出一个日期就可很快推知对应日子是星期几,注意该公式将1,2月当做上一年"13,14"月计算即可。其次是要注意闰年的问题,把握好这两部分就可以写出较为完整的代码了。
代码:
#include <stdio.h>
int main()
{ int Y, M, i, j, day, sumday;//输入年,月,工具变量i,j,天(一号),每月最多天数
scanf("%d %d", &Y, &M);
if (Y % 400 == 0|| (Y % 4 == 0 && Y % 100 != 0) )//判断闰年
{
if (M == 1||M == 3||M == 5||M == 7
||M == 8||M == 10||M == 12)
{
sumday = 31;
}
if (M == 2)
{
sumday = 29;
}
if (M == 4||M == 6||M == 9||M == 11)
{
sumday = 30;
}
}
else
{
if (M == 1||M == 3||M == 5
||M == 7||M == 8||M == 10||M == 12)
{
sumday = 31;
}
if (M == 2)
{
sumday = 28;
}
if (M == 4||M == 6||M == 9||M == 11)
{
sumday = 30;
}
}
if (M == 1||M == 2)
{
M += 12; //一月算做上一年的十三月,二月算做上一年的十四月
Y --;
}
day = (3 + 2 * M + 3 * (M + 1) / 5 + Y + Y / 4 - Y / 100 + Y / 400) % 7;//算出这月一号周几(蔡勒公式)
if (day == 0)
{
day = 7;
}
printf ("Sun Mon Tur Wed Thu Fri Sat \n");
for (i = 1; i <= day - 1; i++)
{ printf (" ");
}
for (j = 1; j <= sumday; j++)
{ printf ("%2d ", j);
if ( (j + day - 1)%7 == 0)
printf("\n");
}
return 0;
}