题目如下:
小 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≤m≤12
输入样例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
我の分析:
问题分析
我们需要生成2025年指定月份的日历,关键点包括:
-
确定每个月的天数
-
确定该月第一天是星期几
-
按照格式输出日历,确保日期对齐
核心算法
-
计算目标月份第一天是星期几(已知2025年1月1日是星期三)
-
输出星期标题(MON到SUN)
-
生成日历日期,先输出空白格直到第一天,然后依次输出日期
代码实现
C++实现
cpp
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
int m;
cin >> m;
vector<int> months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 计算从1月到目标月份前一个月的总天数
int total_days = 0;
for (int i = 0; i < m - 1; i++) {
total_days += months[i];
}
// 计算目标月份第一天的星期(0-星期一,6-星期日)
int first_day = (2 + total_days) % 7; // 1月1日是星期三,对应2
int days = months[m - 1];
// 输出星期标题
cout << "MON TUE WED THU FRI SAT SUN" << endl;
// 输出日历
vector<string> week;
// 添加空白格直到第一天
for (int i = 0; i < first_day; i++) {
week.push_back(" ");
}
// 添加日期
for (int day = 1; day <= days; day++) {
// 格式化为3字符宽度,右对齐
string s = to_string(day);
while (s.length() < 3) {
s = " " + s;
}
week.push_back(s);
// 每满7个日期输出一行
if (week.size() == 7) {
for (int i = 0; i < 7; i++) {
cout << week[i];
if (i < 6) cout << " ";
}
cout << endl;
week.clear();
}
}
// 输出最后一行
if (!week.empty()) {
for (int i = 0; i < week.size(); i++) {
cout << week[i];
if (i < week.size() - 1) cout << " ";
}
cout << endl;
}
return 0;
}
Java实现
java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 计算从1月到目标月份前一个月的总天数
int totalDays = 0;
for (int i = 0; i < m - 1; i++) {
totalDays += months[i];
}
// 计算目标月份第一天的星期(0-星期一,6-星期日)
int firstDay = (2 + totalDays) % 7; // 1月1日是星期三,对应2
int days = months[m - 1];
// 输出星期标题
System.out.println("MON TUE WED THU FRI SAT SUN");
// 输出日历
List<String> week = new ArrayList<>();
// 添加空白格直到第一天
for (int i = 0; i < firstDay; i++) {
week.add(" ");
}
// 添加日期
for (int day = 1; day <= days; day++) {
// 格式化为3字符宽度,右对齐
String s = String.valueOf(day);
while (s.length() < 3) {
s = " " + s;
}
week.add(s);
// 每满7个日期输出一行
if (week.size() == 7) {
for (int i = 0; i < 7; i++) {
System.out.print(week.get(i));
if (i < 6) System.out.print(" ");
}
System.out.println();
week.clear();
}
}
// 输出最后一行
if (!week.isEmpty()) {
for (int i = 0; i < week.size(); i++) {
System.out.print(week.get(i));
if (i < week.size() - 1) System.out.print(" ");
}
System.out.println();
}
scanner.close();
}
}
Python实现
python
def main():
m = int(input().strip())
months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 计算从1月到目标月份前一个月的总天数
total_days = 0
for i in range(m-1):
total_days += months[i]
# 计算目标月份第一天的星期(0-星期一,6-星期日)
first_day = (2 + total_days) % 7 # 1月1日是星期三,对应2
days = months[m-1]
# 输出星期标题
print("MON TUE WED THU FRI SAT SUN")
# 输出日历
week = []
# 添加空白格直到第一天
for i in range(first_day):
week.append(" ")
# 添加日期
for day in range(1, days+1):
# 格式化为3字符宽度,右对齐
s = str(day).rjust(3)
week.append(s)
# 每满7个日期输出一行
if len(week) == 7:
print(' '.join(week))
week = []
# 输出最后一行
if week:
print(' '.join(week))
if __name__ == '__main__':
main()
算法解释
关键步骤
-
计算第一天是星期几:
-
已知2025年1月1日是星期三
-
计算从1月1日到目标月份第一天的总天数
-
使用模7运算确定星期几
-
-
输出格式:
-
星期标题固定为"MON TUE WED THU FRI SAT SUN"
-
日期使用3字符宽度右对齐,确保个位数字与对应星期缩写的最后一个字母对齐
-
-
日历生成:
-
先输出空白格直到第一天
-
然后依次输出日期,每7个日期换行
-
复杂度分析
-
时间复杂度:O(n),其中n是目标月份的天数
-
空间复杂度:O(1),只使用了固定大小的数组