POJ 3393 Lucky and Good Months by Gregorian Calendar 模拟

题目:

http://poj.org/problem?id=3393

题意:

很长的阅读题,要点有以下几点:
- 1752年9月3日~13日共11天不存在。
- 1582年之前(不包括1582)判断闰年的方式是能被4整除
- 1582年及以后判断闰年的方式就是我们常用的:能被400整除,或者能被4整除且不能被100整除
- 1700规定为闰年。
- 每个月的第一个工作日是星期一,这个月就是good month
- 每个月的最后一个工作日是星期五,这个月就是luck month
最后,求给定的时间段内good month和luck month的个数

思路:

模拟,打表,没什么好说的,就是题意十分恶心

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;


typedef long long ll;
const int N = 10010;

int Luck[N][13], Good[N][13];

int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool leap(int y)
{
    if(y == 1700) return true;
    if(y < 1592)
    {
        return y % 4 == 0;
    }
    else
    {
        if((y % 400 == 0) || (y % 100 != 0 && y % 4 == 0)) return true;
        else return false;
    }
}
void table()
{
    int tm = 5;//首先写个程序计算出公元1年1日为周六,这里赋值为前一天,即星期五
    memset(Good, 0, sizeof Good);
    memset(Luck, 0, sizeof Luck);
    //打表计算,把所有的good和luck计算出来
    for(int i = 1; i <= 10000; i++)
    {
        for(int j = 1; j <= 12; j++)
        {
            int d = day[j];
            if(j == 2 && leap(i)) d++;
            for(int k = 1; k <= d;)
            {
                tm = (tm + 1) % 7;
                if(i == 1752 && j == 9)
                {
                    if(k == 2) k = 14;
                    else k++;
                }
                else k++;

                if(k-1 == 1)
                {//本月第一天为周六、日、一,则是good
                    if(tm == 6 || tm == 0 || tm == 1) Good[i][j] = 1;
                }
                if(k-1 == d)
                {//本月最后一天为周五、六、日,则是luck
                    if(tm == 5 || tm == 6 || tm == 0) Luck[i][j] = 1;
                }
            }
        }
    }
}
int main()
{
    table();

    int t, y1, m1, y2, m2;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d%d%d", &y1, &m1, &y2, &m2);
        int luck = 0, good = 0;
        for(int i = y1; i <= y2; i++)
        {
            int st = (i == y1) ? m1 : 1;
            int en = (i == y2) ? m2 : 12;
            for(int j = st; j <= en; j++)
                luck += Luck[i][j], good += Good[i][j];
        }
        printf("%d %d\n", luck, good);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值