100C之11: 三天打鱼两天晒网
Table of Contents
问题
有成语:三天打鱼两天晒网。某人从1990年1月1日起开始三天打鱼两天晒网,问这个人在以后的某一天中是在打鱼还是晒网?
问题分析
这个问题的核心在于找出1990年1月1日以后的某一天距离1990年1月1日有多少天。找到了这个数字,除以5,若余数是1,2,3,那么此人这天打鱼; 否则晒网。
步骤
- 计算从1990年1月1日开始到指定日期有多少天?
- 用计算所得天数除以5;
- 根据余数判断是在打鱼还是晒网。
解决方案
计算天数的子程序为
1: int CountTheDay ( int y, int m, int d ) 2: { 3: int TotalDays; /// Total days untuil current day y:m:d 4: int TotalYears = y - 1990 ;/// Total years untuil current year y 5: int DaysEachMonth[ 12 ] = {31,28,31,30,31,30,31,31,30,31,30,31}; 6: int NumberOfLeapYear ; 7: int DaysOfCurrentYear; 8: int flag;/// whether current year is the leap year 9: 10: /// whether current year the leap year 11: if ( ( 0==y%4 && 0!=y%100 ) || 0==y%400 ) 12: { 13: flag=1; 14: NumberOfLeapYear--; 15: } 16: else 17: flag=0; 18: /// count the total year and the leap years 19: if (floor( ( TotalYears -2 )/4 )< 0) 20: NumberOfLeapYear = 0; 21: else if(floor( ( TotalYears -2 )/4 >= 0 )) 22: NumberOfLeapYear = floor( ( TotalYears -2 )/4) + 1 - flag; 23: /// count the days of current years 24: for (int i = 0; i < m-1; ++i) 25: { 26: DaysOfCurrentYear += DaysEachMonth[ i ]; 27: } 28: DaysOfCurrentYear = ( ( 1==flag ) && ( m>1 ) )?( DaysOfCurrentYear + 1 +d ):( DaysOfCurrentYear +d ); 29: TotalDays = ( ( ( TotalYears-1 ) >=0 )? ( TotalYears-1 ): 0 )*365 + NumberOfLeapYear + DaysOfCurrentYear; 30: return TotalDays; 31: }
主程序为
1: int main(int argc, char *argv[]) 2: { 3: int y,m,d; 4: int Days; 5: y=1993; 6: m=10; 7: d=25; 8: Days=CountTheDay( y,m,d ); 9: /// whether fishing or breaking 10: if ( Days%5==0 || Days%5==4 ) 11: printf ("No fishing!\n"); 12: else 13: printf ("fishing!\n"); 14: return 0; 15: }
关于计算天数
本题的关健在第一步:计算从1990年1月1日开始到指定日期有多少天?我的解决步骤为
- 已经过去了过少整年( 包括闰年和非闰年)?
- 过去的这些年中有多少个闰年?
- 计算最近的这一不完整年过了多少天?(按照非闰年计算)
- 判断最近的这个年份是闰年还是非闰年以及二月份过了没有,修正3中的结果。(如果是闰年且过了二月,则加一;如果不是闰年或者是闰年但是没有过二月,则保持不变)。
作者:emacsun
出处:http://www.cnblogs.com/chaolong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。