N-45. 吻合日 --日期问题
日期问题
想看N-45题解的请目录查找
因为懒所以日期问题一题没写过,什么都不会,来补盲
蔡勒公式
蔡勒公式是求解大部分日期问题的基础,用来推断某年某月某日的星期数。
算星期数的基本思路:
1.找出一个已知年月日和星期数的基点
2.求出基点和所求点的相隔天数
3.相隔天数对7取模,加上基点的星期数,再对7取模。
因此可以找一个比较特殊的日期作为基点,
满足:
1.正好是某年的最后一天(方便计算相隔日期)
2.星期日(方便计算星期数)
设所求日期数为(month, day, year);
要求的相隔日期为 基准所在年与所求年年初的天数d1 + 所求年年初到所求日的天数d2
前者只用将相差年份数 * 365 + 闰年年数
闰年:year % 4 == 0 && year % 100 != 0 || year % 100 == 0 && year % 400 == 0
即膜4余0,膜100不为0,或者膜400余0;
d1 = year * 365 + \([\frac{year}{4}] - [\frac{year}{100}] + [\frac{year}{400}]\)
现在需要求d2
d2是由0-12个月和0-31天构成的
先来研究月数:
每个月至少有28天,我们先加上month * 28,再加上每个月余出来的天数。
这里计算的是到所求月数的月初。
month | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
3 | 0/1 | 3 | 2 | 3 |
month | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|
2 | 3 | 3 | 2 | 3 |
month | 11 | 12 |
---|---|---|
2 | 3 |
发现剩余天数成循环关系,存在循环节{3,2,3,2,3}
3-7月
8-12月
每5个月增加13
N-42
题目描述:
每一年都会有很多特殊的日子,而有一种特殊的方式叫做“吻合日”。“吻合日”的定义为:如果某日的日期对10取模后的值等于该日的星期值(周日视为7),则称该日为“吻合日”。如2021年3月3日为周三,是“吻合日”。Jaanai想要你帮她求出在一段时间范围内的“吻合日”的数量及每个星期值下“吻合日”的具体数量。
输入格式:
包含m组数据(m不给出),每组数据有两行:
第一行三个数,代表起始年月日;(含)
第二行三个数,代表终止年月日。(不含)
输出格式:
共m行,每行八个整数,第一个整数代表给出的时间范围内“吻合日”的总数,第2-8个整数代表周一至周日分别的“吻合日”数量,整数之间由一个空格分隔。
行末没有多余空格,但是有换行符。
如果没有什么思路就可以像我一样暴力分类讨论:
对于每一天都处理一下:
上图是最长的情况下需要求的段,需要根据具体时间再细分一下:
两年数相等,月数相等
两年数相等,月数相差1
两年数相等,月数相差大于1
两年数相差等于1
两年数相差大于1(即图中所示最完整的情况)
#include <stdio.h>
#include <string.h>
int d[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year1, month1, day1, year2, month2, day2;
int cnt[8] = {0};
int ans = 0;
int isleap (int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) return 1;
return 0;
}
int days (int year, int month) {
if (isleap(year) && month == 2) return 29;
return d[month - 1];
}
void query (int year, int month, int day) {
if (month == 1 || month == 2) month += 12, year--;
int res =(day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;
if (res == 0) res = 7;
if (res == day % 10) {
cnt[res] ++; ans ++;
}
}
void solve () {
memset(cnt, 0, sizeof cnt);
ans = 0;
if (year1 == year2 && month1 == month2) {
for (int i = day1; i < day2; i++) query(year1, month1, i);
printf("%d ", ans);
for (int i = 1; i <= 7; i++) {
if (i != 7) printf("%d ", cnt[i]);
else printf("%d\n", cnt[i]);
}
}
else if (year1 == year2 && month2 > month1 + 1) {
for (int i = day1; i <= days(year1, month1); i++) query(year1, month1, i);
for (int i = month1 + 1; i < month2; i++) {
for (int j = 1; j <= days(year1, i); j++) {
query(year1, i, j);
}
}
for (int i = 1; i < day2; i++) query(year2, month2, i);
printf("%d ", ans);
for (int i = 1; i <= 7; i++) {
if (i != 7) printf("%d ", cnt[i]);
else printf("%d\n", cnt[i]);
}
}
else if (year1 == year2) {
for (int i = day1; i <= days(year1, month1); i++) query(year1, month1, i);
for (int i = 1; i < day2; i++) query(year2, month2, i);
printf("%d ", ans);
for (int i = 1; i <= 7; i++) {
if (i != 7) printf("%d ", cnt[i]);
else printf("%d\n", cnt[i]);
}
}
else if (year2 == year1 + 1) {
for (int i = day1; i <= days(year1, month1); i++) query(year1, month1, i);
for (int i = month1 + 1; i <= 12; i++) {
for (int j = 1; j <= days(year1, i); j++) {
query(year1, i, j);
}
}
for (int i = 1; i < month2; i++) {
for (int j = 1; j <= days(year1, i); j++) {
query(year2, i, j);
}
}
for (int i = 1; i < day2; i++) query(year2, month2, i);
printf("%d ", ans);
for (int i = 1; i <= 7; i++) {
if (i != 7) printf("%d ", cnt[i]);
else printf("%d\n", cnt[i]);
}
}
else {
for (int i = day1; i <= days(year1, month1); i++) query(year1, month1, i);
for (int i = month1 + 1; i <= 12; i++) {
for (int j = 1; j <= days(year1, i); j++) {
query(year1, i, j);
}
}
for (int i = year1 + 1; i < year2 ; i++) {
for (int j = 1; j <= 12; j++) {
for (int k = 1; k <= days(i, j); k++) {
query(i, j, k);
}
}
}
for (int i = 1; i < month2; i++) {
for (int j = 1; j <= days(year2, i); j++) {
query(year2, i, j);
}
}
for (int i = 1; i < day2; i++) query(year2, month2, i);
printf("%d ", ans);
for (int i = 1; i <= 7; i++) {
if (i != 7) printf("%d ", cnt[i]);
else printf("%d\n", cnt[i]);
}
}
}
int main () {
while(~scanf("%d%d%d%d%d%d", &year1, &month1, &day1, &year2, &month2, &day2)) {
solve();
}
return 0;
}