按月数 $O(400*12)$
#include <iostream>
using namespace std;
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int week[7];
int main()
{
int n; cin >> n;
// days 某年某月1号距离1900年1月1号多少天
for (int year = 1900, days = 0; year < 1900 + n; year ++)
{
for (int month = 1; month <= 12; month ++)
{
week[(days + 12) % 7] ++; // days + 12 就是当年当月的13号距离1900.1.1多少天
days += months[month];
if (month == 2)
{
if (year % 100 && year % 4 == 0 || year % 400 == 0)
days ++;
}
}
}
for (int i = 5, j = 0; j < 7 ; i = (i + 1) % 7, j ++) cout << week[i] << " ";
return 0;
}
按天数 $O(400 * 365)$
#include <iostream>
using namespace std;
int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int weeks[7];
int getdays(int year, int mon) // 获取某年某月有多少天
{
if (mon != 2) return months[mon];
if (year % 100 && year % 4 == 0 || year % 400 == 0)
return 29;
return 28;
}
int main()
{
int n; cin >> n;
// 从 1900.1.1(周一) 开始按天数
for (int year = 1900, mon = 1, day = 1, week = 0; year < 1900 + n;)
{
if (day == 13) weeks[week] ++;
week = (week + 1) % 7; // 下一天是周几
day ++; // 下一天
if (day > getdays(year, mon)) mon ++, day = 1; // 下一月
if (mon > 12) year ++, mon = 1; // 下一年
}
for (int i = 5, j = 0; j < 7; i = (i + 1) % 7, j ++) cout << weeks[i] << " ";
return 0;
}