✏️ 纠错
第 145 题 / 共 155 题

题目描述

小 A 想制作 2025 年每个月的日历。他希望你能编写一个程序,按照格式输出给定月份的日历。

具体来说,第一行需要输出 MON TUE WED THU FRI SAT SUN,分别表示星期一到星期日。接下来若干行中依次输出这个月所包含的日期,日期的个位需要和对应星期几的缩写最后一个字母对齐。例如,2025 年 9 月 1 日是星期一,在输出九月的日历时,1 号的个位 1 就需要与星期一 MON 的最后一个字母 N 对齐。九月的日历输出效果如下:

MON TUE WED THU FRI SAT SUN
  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

你能帮助小 A 完成日历的制作吗?

输入格式

一行,一个正整数 m,表示需要按照格式输出 2025 年 m 月的日历。

输出格式

输出包含若干行,表示 2025 年 m 月的日历。

输入输出样例

输入 #1

9

输出 #1

MON TUE WED THU FRI SAT SUN
  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

输入 #2

6

输出 #2

MON TUE WED THU FRI SAT SUN
                          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

说明/提示

对于所有测试点,保证 1≤m≤12。

📝 题目解析
【解析】要求根据输入的月份,打印出该月份的日历,以星期为单位进行排版。首先定义数组,用于存储每个月的天数索引1 到12 分别对应1 到12月,输入目标月份,然后打印出星期表头(MON到SUN),并获取该月份的总天数。核心是计算目标月份第一天是星期几,这里以9 月1日为星期一作为基准:若目标月份在9 月之后,则从9月开始,依次累加中间每个月的天数,通过计算得出目标月份1 号的星期数。若目标月份在9 月之前,则从8月开始,依次倒推中间每个月的天数,计算出目标月份1 号的星期数(若结果为0,修正为周日)。输出时,先根据目标月1号的星期数,在月初前打印相应数量的空白(每个空白占4个字符)。然后遍历该月所有天数,每个日期占3个字符(要求右对齐),并根据星期几换行:遇到周日或该月最后一天时换行,其他情况日期之间用空格分隔。

#include <algorithm>
#include <cstdio>

using namespace std;

int days[20] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main() {
    int m;
    scanf("%d", &m);
    printf("MON TUE WED THU FRI SAT SUN\n");
    int d = days[m];

    int w = 1;
    if (m > 9) {
        for (int i = 9; i < m; i++) w = (w + days[i] - 1) % 7 + 1;
    } else if (m < 9) {
        for (int i = 8; i >= m; i--) w = ((w - days[i]) % 7 + 7) % 7;
    }
    if (w == 0) w = 7;

    for (int i = 1; i < w; i++) printf("   ");
    for (int i = 1; i <= d; i++) {
        printf("%3d", i);
        w = w % 7 + 1;
        if (w == 1 || i == d)
            printf("\n");
        else
            printf(" ");
    }
    return 0;
}