avatar
fireworks99
keep hungry keep foolish

吉姆拉尔森计算公式

吉姆拉尔森计算公式:根据日期计算星期几(另有蔡勒公式)

公式

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;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy