zoj3939(打表,基姆拉尔森计算公式,计算某天是星期几的方法)

Edward, the headmaster of the Marjar University, is very busy every day and always forgets the date.

There was one day Edward suddenly found that if Monday was the 1st, 11th or 21st day of that month, he could remember the date clearly in that week. Therefore, he called such week "The Lucky Week".

But now Edward only remembers the date of his first Lucky Week because of the age-related memory loss, and he wants to know the date of the N-th Lucky Week. Can you help him?

Input

There are multiple test cases. The first line of input is an integer T indicating the number of test cases. For each test case:

The only line contains four integers YMD and N (1 ≤ N ≤ 109) indicating the date (Y: year, M: month, D: day) of the Monday of the first Lucky Week and the Edward's query N.

The Monday of the first Lucky Week is between 1st Jan, 1753 and 31st Dec, 9999 (inclusive).

Output

For each case, print the date of the Monday of the N-th Lucky Week.

Sample Input

2
2016 4 11 2
2016 1 11 10

Sample Output

2016 7 11
2017 9 11

题意:如果一天的日期是1,11,21,并且这天是星期一,那么这周就是幸运周,现在给出一个日期(第一个幸运周周一)和n,问你第n个幸运周是什么时间,就是打印那周周一。

开始的时候我们还在想这肯定有循环节,那么闰年会打破平衡,并且不知道下次的周一会变成周几,那么400*7肯定是循环节,后来想先看前400年的表,再打一个后400年看规律,结果第一个就找到了。当时我们是从1753年开始打的表,后来我想了下从0~399其实就可以,然后试了下真的行。这里为大家介绍一个计算某天使星期几的方法。

基姆拉尔森计算公式:W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7 

在公式中d表示日期中的日数,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。

(摘自百度百科)并且这个公式中的d表示日期+1,w就直接是周几。

这里给出基础板子:

#include<stdio.h>
int main()
{
    int y,m,d;
    while(~scanf("%d%d%d",&y,&m,&d))
    {
        if(m==1||m==2)
        {
            m+=12;
            y--;
        }
        int w=(d+1+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;
        printf("%d\n",w);
    }
    return 0;
}

这道题的代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
#include<iostream>
#include<map>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int v[3000][500];
int r;
void aa()
{
    int yy,mm,dd;
    r=0;
    for(int i=0;i<400;i++)
    {
        for(int j=1;j<=12;j++)
        {
            for(int k=1;k<30;k+=10)
            {
                yy=i;
                mm=j;
                dd=k;
                if(mm==1||mm==2)
                    mm+=12,yy--;
                int w=(dd+1+2*mm+3*(mm+1)/5+yy+yy/4-yy/100+yy/400)%7;
                if(w==1)
                {
                    v[r][1]=i;
                    v[r][2]=j;
                    v[r][3]=k;
                    r++;
                }
            }
        }
    }
}
int main()
{
    aa();
    int t,y,m,d,n;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            scanf("%d%d%d%d",&y,&m,&d,&n);
            n--;
            int res=y/400;
            y%=400;
            int flag;
            for(int i=0; i<r; i++)
            {
                if(v[i][1]==y&&v[i][2]==m&&v[i][3]==d)
                    flag=i;
            }
            res+=(flag+n)/2058;
            flag=(flag+n)%2058;
            res=res*400+v[flag][1];
            printf("%d %d %d\n",res,v[flag][2],v[flag][3]);
        }
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/zezzezzez/article/details/80147862