poj3393

来源:互联网 发布:易语言手机版远控源码 编辑:程序博客网 时间:2024/04/30 08:19

题目不难,主要是细节太多,很容易产生错误,模拟水题,但不容易AC。

首先是题目信息太多了(废话太多),所以不容易发现有用的信息。所以耐心是关键。

分析题目信息,主要有用信息如下:

1)1年1月1日为星期6

2)润年的判定方法如下:

 若year<1582,则year%4==0 为润年,否则为平年

 若year>=1582,则year%4==0 && year%100!=0 || year%400==0 为润年,否则为平年,注意1700规定为润年。

3)1752年是不寻常的年份,其9月从3号开始到13号结束都没有天数。

只要把上面的信息挖掘出出来,剩下的就是模拟水题了。

思路如下:令输入为sy,sm,ey,em分别表示起始年、起始月、结束年、结束月

要想一个月是good,则有题目定义:该月的第一个工作日为星期1,转化过来就是改月的第一天是星期6、星期天、或者星期一。当然对于1752年9月比较特殊,因为其3号是没有的,故此时判断条件为星期天或者星期一。

同样要想一个月是lucky,则由题目定义:该月的最后一个工作日为星期5,转化过来就是该月的最后一天为星期6、星期天、或者星期5。这里没有特殊情况,因为1752年9月到13号就结束了,故剩余的还多余2天。

首先可以计算出,sy年sm月第一天是星期几,然后判断满足good条件,计算该月最后一天,判断是否满足lucky条件,注意1752年9月特殊情况处理,直至到达ey年em月为止,计数good和lucky月份个数。

另外就是星期的推算公式了:星期1——天用数字1——7表示

若x日期为星期day,而y日期与x日期相隔n天(包含y不包含x),其y星期D为:D=n%7+day

若D!=7,则D%=7 否则 即为D=7

下面是代码:156K+16MS

#include<stdio.h>#include<stdlib.h>#include<string.h>int sy,sm,ey,em,c; //起始年、起始月、结束年、结束月int lucky,good; //计数月份int mon[13]={0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //平年每月天数bool Is_leapyear(int year){ //根据题目判断是否为润年,注意1700特殊处理if(year<1582){if(year%4==0)return true;return false;}else{if(year%4==0 && year%100!=0 || year%400==0 || year==1700)return true;elsereturn false;}}int cal(int year,int month){ // 推算起始年、起始月的第一天int day=0;for(int i=1;i<year;i++){ // 累加起始年之前的所有天数if(Is_leapyear(i)) //润年day+=366;else //平年day+=365;}for(int i=1;i<month;i++) //累加起始月之前的所有天数    if(i==2 && Is_leapyear(year)) //润年二月份特殊处理day+=(mon[i]+1);elseday+=mon[i];if(year>1752 || year==1752 && month>=10) // 若在起始日期在1752年9月份以后,则要减去1752年空缺的11天day-=11;  //至此已经计算起始日期距离1年1月1日的天数day=day%7+6; //计算起始日期为星期几if(day!=7)return day%7;elsereturn day;}int main(){scanf("%d",&c);    while(c--){scanf("%d%d%d%d",&sy,&sm,&ey,&em); //输入起始日期和结束日期int first=cal(sy,sm),last,year=sy,month=sm; //计算起始日期星期//printf("%d\n",first);lucky=good=0; //初始化为0while(true){ // 循环判断每个月是否属于good or lucky月份if(year==ey && month>em || year>ey) //若循环结束break;    if(month==9 && year==1752){ // 若为特殊情况,即为1752年9月份if(first==7 || first==1) //若该月第一天为星期天或者星期一则为goodgood++;last=18%7+first; //计算last,由于空缺11天,故为(30-11-1)%7+first}else{ //普通情况if(first==7 || first==1 || first==6)  //若该月第一天为星期天、星期六、或者星期1则为goodgood++;if(Is_leapyear(year) && month==2)  //计算该月最后一天last=mon[month]%7+first;    else    last=(mon[month]-1)%7+first;}if(last!=7) last%=7; //计算最后一天星期if(last==6 || last==7 || last==5) //若为星期六、星期天、星期一则为lucky月份lucky++;first=last%7+1; // 计算下一个月的第一天星期if(month==12){ //若为最后一个月,则下一个日期要特殊处理month=1;year++;}elsemonth++;}printf("%d %d\n",lucky,good); //输出}return 0;}


 

0 0
原创粉丝点击