题解
2026-02-26 13:21:19
发布于:浙江
42阅读
0回复
0点赞
题目解析
- 输入输出:输入一个整数 ()表示月份。输出 年 月的格式化日历,首行为星期标题,后续为日期,日期个位需与对应星期缩写末字母对齐。
- 数据范围:月份范围 到 , 年非闰年, 月为 天。
- 复杂度要求:固定输出 个位置( 行 列)或更少,时间复杂度 ,空间复杂度 。
- 算法知识点:
Zeller公式(蔡勒公式)、日期计算、格式化输出
思路解析
- 计算星期:利用 Zeller 公式 计算 年 月 日是星期几。由于 Zeller 公式中 月和 月需视为上一年的 月和 月,代码中进行了特殊处理。公式计算结果 的范围为 (周六)到 (周五),通过映射数组
weekdays转换为:周一=,周二=,...,周六=,周日=,方便后续定位。 - 确定月份天数:使用数组
months存储 年各月天数(非闰年, 月为 天)。 - 格式化输出:
- 首行固定输出星期标题,每个缩写占 位字符。
- 使用循环遍历 到 (最多 行),每个位置占 位宽度(
%3d或三个空格)。 - 当循环变量 等于计算出的星期值时,开始填入日期(从 开始)。
- 填入日期前输出空格占位,填入后按 位右对齐格式输出;日期填完后提前终止循环。
- 每 个位置换行,否则输出空格分隔。
完整代码
#include <bits/stdc++.h>
using namespace std;
// Zeller公式结果映射:0=周六,1=周日,2=周一...6=周五 → 转换为 6=周六,7=周日,1=周一...5=周五
int weekdays[] = {6, 7, 1, 2, 3, 4, 5};
// 2025年各月天数(非闰年)
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Zeller公式(蔡勒公式):计算y年m月d日是星期几(注意1月2月要当作去年13月14月)
int Zeller(int y, int m, int d) {
if (m == 1 || m == 2) {
m += 12;
y--;
}
int q = d;
int k = y % 100; // 年份后两位
int j = y / 100; // 年份前两位
// h: 0=周六, 1=周日, 2=周一, ..., 6=周五
int h = (q + (26 * (m + 1)) / 10 + k + k / 4 + 5 * j + j / 4) % 7;
return h;
}
int main() {
int m;
cin >> m;
// 获取1号对应的星期位置(1=周一, 7=周日)
int week = weekdays[Zeller(2025, m, 1)];
cout << "MON TUE WED THU FRI SAT SUN" << endl;
int start = 0; // 当前应输出的日期,0表示尚未开始
// 最多6行(42个位置),遍历每个格子
for (int i = 1; i <= 42; i++) {
if (i == week) start = 1; // 到达1号所在位置,开始填数
if (start != 0 && start <= months[m]) {
// 关键:%3d确保右对齐占3位,与星期缩写宽度一致
printf("%3d", start++);
} else if (start <= months[m]) {
// 1号之前,输出3个空格占位
printf(" ");
} else {
// 日期已输出完毕,提前结束
break;
}
// 关键:每7个格子换行,否则输出空格分隔
if (i % 7 == 0) cout << endl;
else cout << " ";
}
return 0;
}
这里空空如也

有帮助,赞一个