所有评测用例都满足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050。
#include<iostream> #include<cstdio> using namespace std; #define BGY 1850 #define MXY 2050+3 int fg[MXY] = { 0 }; void pre(){ // 计算第i年(含)之前总共有几个闰年 for (int i = BGY+1; i < MXY; i++){ fg[i] = fg[i - 1]; if (i % 400 == 0 || (i % 4 == 0 && i % 100 != 0)) fg[i] ++; } // 这样fg[i]>fg[i-1]就同时意味着第i年为闰年 } // 普通情况下12个月的天数 int mth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; void solve(int y,int a,int b,int c){ // 天数 = 365 * 年份 + 闰年数 int d = (y - BGY) * 365 + fg[y - 1]; for (int i = 1; i < a; i++){ // 目的月份前的天数和 d += mth[i]; } // 闰年2月多一天 if (a > 2 && fg[y] > fg[y - 1]) d++; // 得到目标月的第一天是星期几 int k = (d + 1) % 7 + 1; int z = 1; // 模拟过家家~开始数符合目标的天数 while (true){ if (k == c) b--; if (b == 0 && k == c) break; k++; z++; // 用 k % 7 需要注意偏移问题 if (k > 7) k -= 7; } // 计算日期超出月份限制 if (z > mth[a]){ // 除非是闰年2月29日,否则超限则错 if (!(a == 2 && fg[y] > fg[y - 1] && z == 29)){ cout << "none" << endl; return; } } // 输出 // 原则上cin/cout和printf/scanf不要混用 // 会增加时间,不过这里时间没问题 printf("%d/d/d\n", y, a, z); } int main(){ pre(); // 预处理闰年问题 int a, b, c, y1, y2; cin >> a >> b >> c >> y1 >> y2; for (int i = y1; i <= y2; i++){ // 可以选择连续解决 // 但单独写貌似简单 solve(i,a,b,c); } return 0; }