Openjudge 打印月历

http://noi.openjudge.cn/ch0113/24/

描述
给定年月,打印当月的月历表。

输入
输入为一行两个整数,第一个整数是年份year(1900 ≤ year ≤ 2099),第二个整数是月份month(1 ≤ month ≤ 12),中间用单个空格隔开。

输出
输出为月历表。月历表第一行为星期表头,如下所示:
Sun Mon Tue Wed Thu Fri Sat
其余各行一次是当月各天的日期,从1日开始到31日(30日或28日)。
日期数字应于星期表头右对齐,即各位数与星期表头相应缩写的最后一个字母对齐。日期中间用空格分隔出空白。

样例输入

1
2006 5

样例输出

1
2
3
4
5
6
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日是周一。

需要使用基姆拉尔森公式计算某日期是星期几。
设日期为y年m月d日:
W=(d+2m+3(m+1)/5+y+y/4-y/100+y/400+1)%7
W是0~6,0代表周日,6代表周六。
注意:把一月和二月看成是上一年的十三月和十四月。例:如果是2004-1-10,则换算成:2003-13-10来代入公式计算。

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
32
33
34
#include<cstdio>
using namespace std;
int kimlarsen(int y,int m,int d) {
    if (m == 1 || m == 2) {
        y--;
        m += 12;
    }
    return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) % 7;
}
int getMonthDay(int y, int m) {
    switch (m) {
    case 1: case 3: case 5: case 7:
    case 8: case 10: case 12:
        return 31;
    case 2:
        return 28 + (y % 4 == 0 && y % 100 != 0 || y % 400 == 0);
    case 4: case 6: case 9: case 11:
        return 30;
    }
}
void output(int startPos, int days) {
    printf("Sun Mon Tue Wed Thu Fri Sat\n");
    for (int i = 0; i < startPos; i++)printf("    ");
    for (int i = 1; i <= days; i++) {
        printf("%3d", i);
        if ((i + startPos) % 7 == 0)printf("\n");
        else printf(" ");
    }
}
int main() {
    int y, m;
    scanf("%d %d", &y, &m);
    output(kimlarsen(y, m, 1), getMonthDay(y, m));
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注