吉姆拉尔森计算公式
吉姆拉尔森计算公式:根据日期计算星期几(另有蔡勒公式)
公式
w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100 + y / 400) % 7;
小注
d -> day m -> month y -> year
w == 0 ? 7 : w ;
特别之处
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
Code
int cal(int y, int m, int d)
{
if(m < 3)
{
m += 12;
--y;
}
int w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100 + y / 400) % 7;
return w == 0 ? 7 : w;
}
例题HDU 6112 今夕何夕
给出一个日期,求下一个同月同日同星期的一天在哪一年
思路
用公式计算星期几,枚举年份
Code
#include <cstdio>
#include <iostream>
using namespace std;
int y, m, d;
bool judge(int year)
{
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return 1;
else
return 0;
}
bool special(int now_year)
{
if(judge(y) && !judge(now_year) && (m == 2 && d == 29))
return 1;
else
return 0;
}
int cal(int y, int m, int d)
{
if(m < 3)
{
m += 12;
--y;
}
int w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100 + y / 400) % 7;
return w == 0 ? 7 : w;
}
int main()
{
int t;
cin >> t;
while(t--)
{
scanf("%d-%d-%d", &y, &m, &d);
int mine = cal(y, m, d);
for(int i = y + 1; ; ++i)
{
int yours = cal(i, m, d);
if(special(i))
continue;
if(mine == yours)
{
cout << i << '\n';
break;
}
}
}
return 0;
}