欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ZOJ - 3939 The Lucky Week【简单方法】

程序员文章站 2022-07-15 16:16:55
...

题目

传送门
ZOJ - 3939 The Lucky Week【简单方法】

Sample Input
2
2016 4 11 2
2016 1 11 10
Sample Output
2016 7 11
2017 9 11

题意:t组数据,给出四个数,x,y,z,m,其中 x,y,z,分别是第一个幸运日的年月日,幸运日的定义为每月的1,11,或21,号且星期一,问第m个幸运日的年月日
注意第一个幸运日的范围为(1753 1.1~9999 12 .31)并不是要求的所有幸运日都在这个范围内

思路:暴力的话,1e9肯定超时,我们可以找下规律,我们发现从第一个幸运日开始到400年之后的同样的月份和日期例从2016 4 11 ~2416 4 11 总共有2059个幸运日,每个幸运日都符合这个规律,这样的话我们直接看要求的是第几个,把它减一,看他里面有几个2058,同时年份加上400,最后一个一个寻找,具体看代码(实力有限,大佬勿喷)

AC code

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
using namespace std;
int t,x,y,z,m;
int a[2][14]={{0,31,29,31,30,31,30,31,31,30,31,30,31},{0,31,28,31,30,31,30,31,31,30,31,30,31}};//a[0]闰年,a[1]平年
void solve()
{
    m--;
    int p,s=0;
   int k=m/2058;//1~2059这点一定要注意除上2058
    m-=k*2058;
    x+=400*k;
    while(s<m)
{
    if(((x%4==0)&&(x%100!=0))||(x%400==0))p=0;//判断是否闰年
       else p=1;
    z+=7;//保证每次都是星期一
    if(z>a[p][y])
    {
        z-=a[p][y];
        y++;//下一月
        if(y>12)
        {
            y-=12;
            x++;//下一年
        }
    }
    if(z==1||z==11||z==21)
    {
      s++;
    }
}
printf("%d %d %d\n",x,y,z);
}
int main()
{
    ios::sync_with_stdio(0);
    cin>>t;
    while(t--)
    {
        cin>>x>>y>>z>>m;
       solve();
    }
}

一直不知道该除以几,推了一大会儿1~2059除以2058,对于星期周期,1—8除以7
例如第一天星期1,问第8天星期几,,8-1,7-7*7/7=0,是星期1,我真是太菜了…,大佬有任何关于周期好的技巧和方法,欢迎在下方评论qaq;

相关标签: 找规律