ZOJ - 3939(日期规律)

题目:click
题意:星期一在每个月的1号,11号,21号,则是幸运的,给定一个时间,问从此开始的第N个幸运的日期是什么。

N是非常大的,打表找个规律,从1753-1-1开始找1月1号的年份存下来,暴力找到是56,112,确定周期是52,相减得年份周期是400,之间有2058个幸运周。之后直接暴力即可。中途注意一些细节,可以带入具体的边界值进行运算规律。
(打表代码)

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
const int mod=998244353;
int a[20]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int b[10]={5,6,11,6};
struct A {
    int m,d,y;
}que[1000100];
int len=0;
int main()
{
    int year=1753,month=1,day=1;
    int xq=1;
    int tot=0;
    int sum=900000;
    while(sum--)
    {
        if((day==1||day==11||day==21)&&xq==1)
        {
            if(day==1&&month==1)
            {
                que[len].y=year;
                que[len].d=day;
                que[len++].m=month;
             //   cout<<year<<" "<<month<<" "<<day<<endl;
            }
        }
        if((year%4==0&&year%100!=0)||year%400==0)
        {
            a[2]=29;
        }
        else
        {
            a[2]=28;
        }
        day++;
        xq++;
        tot++;
        if(xq>7)
            xq-=7;
        if(day>a[month])
        {
            month++;
            day=1;
            if(month>12)
            {
                year++;
                month-=12;
            }
        }
    }
    int i;
    len--;
    for(i=0;i<len;i++)
    {
        que[i].d=que[i+1].y-que[i].y;
        //cout<<que[i].d<<endl;
    }
 //   cout<<len<<endl;
  //  return 0;
     for(int temp=1;temp<=150;temp++)
    {
        for(i=0;i+temp<len;i++)
        {
            if(que[i].d==que[i+temp].d)
            continue;
            else
                break;
        }
        if(i+temp>=len)
        printf("%d\n",temp);
    }
    cout<<que[56].y<<" "<<que[0].y<<" "<<que[56].y-que[0].y<<endl;
    return 0;
}

预先处理出2058*2的一个循环表。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 200005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
int a[20]={0,31,28,31,30,31,30,31,31,30,31,30,31};
struct A {
    int y,d,m;
};
map<int,A>hh;
void init()
{
    int year=1753,month=1,day=1;
    int xq=1;
    int len=0;
    int sum=400*366;
    while(sum--)
    {
        if((day==1||day==11||day==21)&&xq==1)
        {
                if(year==2153&&month==1&&day==1)
                break;
                len++;
                A temp;
                temp.y=year,temp.d=day,temp.m=month;
                hh[len]=temp;
              //  cout<<year<<month<<day<<endl;
        }
        if((year%4==0&&year%100!=0)||year%400==0)
        {
            a[2]=29;
        }
        else
        {
            a[2]=28;
        }
        day++;
        xq++;
        if(xq>7)
            xq-=7;
        if(day>a[month])
        {
            month++;
            day=1;
            if(month>12)
            {
                year++;
                month-=12;
            }
        }
    }
    for(int i=1;i<=2058;i++)
    {
        A temp;
        temp.y=hh[i].y+400;
        temp.d=hh[i].d;
        temp.m=hh[i].m;
        len++;
        hh[len]=temp;
    }
}
int main()
{
    init();
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int Y,M,D,N;
        scanf("%d %d %d %d",&Y,&M,&D,&N);
        int temp=(Y-1753)/400;
        int temp1=Y-400*temp;
        for(int i=1;i<=2058;i++)
        {
            if(hh[i].y==temp1&&hh[i].m==M&&hh[i].d==D)
            {
                temp=i;
                break;
            }
        }
        N--;
        int t1=N/2058;
        int t2=Y+400*t1;
        N-=t1*2058;
        while(N--)
        {
            temp++;
        }
        t2+=hh[temp].y-temp1;
        printf("%d %d %d\n",t2,hh[temp].m,hh[temp].d);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值