POJ 3393 Lucky and Good Months by Gregorian Calendar

这篇博客详细介绍了格里高利历(Gregorian Calendar)的规则,包括平年和闰年的天数,以及判断闰年的两种标准。1582年是一个重要的转折点,1700年和1752年的特殊规定也在文中提及。起始日期为1年1月1日,是星期六。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源

题意:
Gregorian Calendar格里高公历 就是现在广泛使用公历(西历),下面简称GC
GC平年有365天,闰年366天(2月多1天)
GC有12个月,各月的天数和现在的使用的西历一致
GC在1582年之前(不包括1582),若该年份能被4整除,则为闰年
GC在1582年之后(包括1582),判断闰年的标准(满足下面随便一个):
(1) 能被4整除,但不能被100整除;
(2) 能被400整除。
由于历史原因,GC规定1700年无条件为闰年
由于历史原因,GC规定1752年9月3日~13日共11天不存在,即1752年9月只有19天

GC的起始日期为 1年1月1号,该日为星期六

先把表打出来 最后只需相减就行。good和luck存的是从 1 year 1 month到 i year j month的和。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#define inf 0x3f3f3f3f
#define ll long long
#define mod 99991
using namespace std;
int good[100001][13];
int luck[100001][13];
int leap[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int ping[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int week = 6;
void assignMent(int i,int j){
    if(j==1){
        good[i][j]=good[i-1][12];
        luck[i][j]=luck[i-1][12];
    }
    else{
        good[i][j]=good[i][j-1];
        luck[i][j]=luck[i][j-1];
    }
    if(week==0||week==6||week==1){
        good[i][j]++;
    }
}
void changeWeek(int i,int j,int day){
    week = (week+day)%7;
    if(week==0||week==6||week==1){
        luck[i][j]++;
    }
}
bool isOk(int i){
    if(i < 1582){
        if(i%4==0)return true;
        return false;
    }
    if((i%4==0&&i%100!=0)||i%400==0||i==1700){
        return true;
    }
    return false;
}
void cal_1_10000(){
    memset(good,0,sizeof(good));
    memset(luck,0,sizeof(luck));
    for(int i = 1; i <= 10000; ++i){
        bool flag = isOk(i);
        for(int j = 1; j <= 12; ++j){
            assignMent(i,j);
            if(i==1752&&j==9){
                changeWeek(i,j,19);
            }
            else if(flag){
                changeWeek(i,j,leap[j]);
            }
            else{
                changeWeek(i,j,ping[j]);
            }
        }
    }
}
int main(){
    cal_1_10000();
    int T;
    scanf("%d",&T);
    int y1,m1,y2,m2;
    while(T--){
        scanf("%d%d%d%d",&y1,&m1,&y2,&m2);
        if(y1 > y2){swap(y1,y2);swap(m1,m2);}
        else if(y1==y2&&m1>m2){swap(m1,m2);}
        int ans1,ans2;
        if(m1 == 1){
            ans1 = good[y2][m2]-good[y1-1][12];
            ans2 = luck[y2][m2]-luck[y1-1][12];
        }
        else{
            ans1 = good[y2][m2]-good[y1][m1-1];
            ans2 = luck[y2][m2]-luck[y1][m1-1];
        }
        printf("%d %d\n",ans2,ans1);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值