按闰年规则确定二月天数,再依次扣除每月天数定位日期。
OJ: shumeng
题目 ID: CSP201509B
难度:入门
标签:模拟日期
日期: 2026-07-31 16:21
形式化题目
给定年份
思路
先看一个从 1 月 1 日逐日推进的基准程序,它一天一天地数,直观但常数较大:
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:21
* update_at: 2026-08-17 22:55
*/
// brute.cpp:从 1 月 1 日开始逐日推进。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int year, target_day;
cin >> year >> target_day;
// 从 1 月 1 日开始逐日推进,走满 target_day 天。
int month = 1, day = 1;
bool leap = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
int days[13] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
if (leap) days[2] = 29;
for (int count = 1; count < target_day; count++) {
day++;
if (day > days[month]) {
month++;
day = 1;
}
}
cout << month << '\n' << day << '\n';
return 0;
}brute.cpp 每走一天就更新日期,逻辑最贴近直觉,适合作为对拍基准。正式做法按月处理,更快:
- 闰年判断:年份是 400 的倍数,或是 4 的倍数但不是 100 的倍数,则 2 月有 29 天,否则 28 天。
- 逐月扣除:从 1 月开始,用
d依次减去每个月天数;第一次不能再减时,当前月份就是答案,剩下的d就是该月内的日期。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:21
* update_at: 2026-08-17 22:55
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int year, day;
cin >> year >> day;
// 每月天数,2 月根据闰年规则改为 29 天。
int days[13] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) days[2] = 29;
// 依次扣除每个月,剩余的天数就是该月内的日期。
int month = 1;
while (day > days[month]) {
day -= days[month];
month++;
}
cout << month << '\n' << day << '\n';
return 0;
}复杂度
- 时间:最多处理 12 个月,
。 - 空间:常量空间,
。
总结
日期换算先判断闰年,再把“年内第几天”逐月消耗,能避免手写复杂的月份边界公式。逐日模拟和逐月扣除是同一思路的两种粒度,前者易懂、后者高效。