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

好大的一道模拟题,直接当阅读理解看了。下面是大神写的题意,解释的好详细。

定义:

Goog month : 该月第一个工作日为星期一的月份

Luckly month: 该月最后一个工作日为星期五的月份

问: 给定一个Gregorian Calendar格里高公历的 时间闭区间(就是包括端点的年月了)

【开始年、月】~【结束年、月】

在这个时间区间内,有多少个Goog month,有多少个Luckly month

文章要点:

Gregorian Calendar格里高公历 就是现在广泛使用公历(西历),下面简称GC

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

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一星期有7天,排序为Sun,Mon,Tue,Wed,Thu,Fri,Sat,和现在的星期一致,其中Mon到Fri为工作日,Sun和Sat为休息日

解题思路:

直接模拟就OK了,水题

先做一个判断闰年的函数 leap()

输入时间区间的  起始年sy月sm  终止年ey月em 后

先计算1年1月到sy年sm-1月(若sm=1,则计算到sy-1年12月)的天数day

注意此时day的天数刚好计算到sm-1月的最后一天

若day+1,则恰好进入所输入的时间区间【开始年、月】~【结束年、月】的第一天

计算day时要注意:

(1)       1582年前后闰年判断标准改变了

(2)       1700无条件闰年

(3)       1752年9月少了11天

判断第day天是星期几:

由于1年1月1号为星期六,一星期有7天,

因此 (day+5)%7就能计算第day天是星期几

不能直接day%7,day%7就是默认1年1月1号为星期日,至于为什么要先+5,这个不难推导,读者自己想想就明白了

判断某月是不是Good month和Luckly month:

计算天数day后,令day++,进入sm的1号

此时判断sm的1号是不是为Good month,使用上面给出计算第day天是星期几的方法,若

1号为星期日(0)、星期六(6)或星期一(1),则该月为Good month

从sm月开始,把天数day逐月递增,逐月判断该月是否为Good month,判断方法都是一样的。

不难发现,若第k月为Good month,则第k-1月必定为Luckly month,因此两个计数器同时增加即可。

注意3点:

(1)       边界:若sm为Good month,计数器good++,但计数器luck不变,因为sm-1月不在时间区间内。 若计算到em为Good month,则计数器luck++,good不变,因为day一开始就+1了,当day逐月递增到em时,实则day此时为第em+1月的1号,此时判断的是em+1月是否为Good month,若是,则第em月为Luckly month,但em+1月在时间区间内,不计入计数器

(2)       逐月递增时,若到达1752年9月,要 减11天

(3)       闰年平年的月份天数不同

按大神的思路敲出来的代码。。。模拟题,好忧桑啊。

 #include<stdio.h>
#include<string.h>
enum week {sun,mon,tue,wen,thu,fri,sat};//定义枚举类型
int Month[] = {,,,,,,,,,,,,};//平年月份
int Lmonth[] = {,,,,,,,,,,,,};//闰年月份 bool is_leap_year(int year)//判断是否是闰年
{
if(year <= )
{
if(year% == )
return true;
return false;
} else
{
if(year == )
return true; if((year% == && year%!=)||(year% == ))
return true;
}
return false;
} int main()
{
int test;
int sy,sm,ey,em,day;
int *pm;
scanf("%d",&test);
while(test--)
{
scanf("%d %d %d %d",&sy,&sm,&ey,&em);
day = ;//计算从1年1月1号到sy年sm月的第一天共有几天;
for(int i = ; i < sy; i++)
{
if(is_leap_year(i))
day += ;
else day += ;
} bool flag = is_leap_year(sy);
for(int i = ; i < sm; i++)
{
if(flag)
day += Lmonth[i];
else day += Month[i];
} if(sy > )
day -= ;
else if(sy == && sm > )
day -= ; int luck,good;
luck = good = ;
if((day+)% <= mon || (day+)% == sat)
good++;//如果sy年sm月是good月,good++,但luck不变,因为sm-1月才是luck月 int j;
for(int i = sy; i < ey; i++)//从sy年枚举到ey-1年
{
if(is_leap_year(i))
pm = Lmonth;
else pm = Month;
//j代表该年的起始月
if(i == sy)
j = sm;
else j = ; for( ; j <= ; j++)//枚举第i年的每一月
{
day += *(pm+j); if(i == && j == )
day -= ; if((day+)% <= mon || (day+)% == sat)
{
good++;
luck++;
}
} }
//枚举判断ey年的每一月
if(is_leap_year(ey))
pm = Lmonth;
else pm = Month; if(ey == sy)
j = sm;
else j = ;//对起始年份相同的特殊处理 for(; j <= em; j++)
{
day += *(pm+j); if(ey == && j == )
day -= ; if( (day+)% <= mon || (day+)% == sat)
{
if(j != em)
good++;//当j = em时说明em+1月是good月,超出范围,故不加1
luck++;
}
}
printf("%d %d\n",luck,good);
}
return ;
}

Lucky and Good Months by Gregorian Calendar(模拟)的更多相关文章

  1. POJ 3393 Lucky and Good Months by Gregorian Calendar 模拟题

    题目:http://poj.org/problem?id=3393 不多说了,简单模拟题,因为粗心写错了两个字母,导致错了N遍,模拟还是一贯的恶心,代码实在不想优化了,写的难看了点.. #includ ...

  2. poj 3393 Lucky and Good Months by Gregorian Calendar(模拟)

    题目:http://poj.org/problem?id=3393一道题目挺长的模拟题,参考了网上大神的题解. #include <iostream> #include <cstdi ...

  3. Lucky and Good Months by Gregorian Calendar - POJ3393模拟

    Lucky and Good Months by Gregorian Calendar Time Limit: 1000MS Memory Limit: 65536K Description Have ...

  4. POJ 3393:Lucky and Good Months by Gregorian Calendar 年+星期 模拟

    Lucky and Good Months by Gregorian Calendar Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  5. Lucky and Good Months by Gregorian Calendar(poj 3393)

    大致题意: 科普文一篇,文章80%都是无用信息,因为都是常识,但是又不得不看,因为有20%是常人不知道的历史常识. 定义: Goog month : 该月第一个工作日为星期一的月份 Luckly mo ...

  6. POJ 3393 Lucky and Good Months by Gregorian Calendar

    http://poj.org/problem?id=3393 题意 : 对于这篇长长的英语阅读,表示无语无语再无语,花了好长时间,终于读完了.题目中规定每周的周六日为假日,其他为工作日,若是一个月的第 ...

  7. 三部曲二(基本算法、动态规划、搜索)-1003-Lucky and Good Months by Gregorian Calendar

    模拟加阅读题......虽然很多事常识性的知识,但也有许多不知道的知识,关键是不读不知道那些是已经知道的那些不是,许多重要的信息零散的分布在一大坨英文里,读起来很痛苦......自己读了一遍,读的晕晕 ...

  8. 快速切题 sgu115. Calendar 模拟 难度:0

    115. Calendar time limit per test: 0.25 sec. memory limit per test: 4096 KB First year of new millen ...

  9. poj3393[模拟题]

    Lucky and Good Months by Gregorian Calendar Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

随机推荐

  1. tcmalloc资料

    1. 确定dylib在max os是可以成功的. http://lists.apple.com/archives/perfoptimization-dev/2008/Dec/msg00002.html ...

  2. Java基础知识强化之集合框架笔记33:Arrays工具类中asList()方法的使用

    1. Arrays工具类中asList()方法的使用 public static <T> List<T> asList(T... a): 把数组转成集合 注意事项: 虽然可以把 ...

  3. Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案

    1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...

  4. Linux - CentOS6.5服务器搭建与初始化配置详解(上)

    1.新建一个虚拟机 选择典型 单机下一步 p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm 0cm 0.0001pt; text-align: ...

  5. mysql 操作指令笔记

    设置区分大小写: 打开my.ini,最后加入: [mysqld] lower_case_table_names=2 (2表示区分大小写,但仅限于字段,数据库名.表名.存储过程名都是小写的) 查看方法: ...

  6. android MediaCodec 音频编解码的实现——转码

    原文地址:http://blog.csdn.net/tinsanmr/article/details/51049179 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...

  7. poj 3565 ants

    /* poj 3565 递归分治 还有用KM的做法 这里写的分治 按紫书上的方法 不过那里说的有点冗杂了 可以简化一下 首先为啥可以分治 也就是分成子问题解决 只要有一个集合 黑白的个数相等 就一定能 ...

  8. 19、XHTML

    XHTML 可扩展超文本标签语言(EXtensible HyperText Markup Language). 是一种 W3C 标准. 更严格,更纯净的HTML代码. 目标是取代HTML代码. XHT ...

  9. SQL server 使用触发器跨数据库备份数据

    create database TriggerTest create table transInfo2 --交易信息表 ( cardID ) not null, --卡号 transType ) no ...

  10. 强制关闭myeclipse出现的问题

    重启时,可能会出现打不开关闭前所在的workspace.其他workspace可以正常打开. 今天遇到这个问题,以前就遇到过,但是忘记如何解决了.今天在我等了十多分钟后,神奇的myeclipse自己起 ...