1.问题描述
描述
给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期)。
只有闰年有2月29日,满足以下一个条件的年份为闰年:
1. 年份能被4整除但不能被100整除
2. 年份能被400整除
输入
第一行为一个整数T,表示数据组数。之后每组数据包含两行。每一行格式为"month day, year",表示一个日期。month为{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"}中的一个字符串。day与year为两个数字。
数据保证给定的日期合法且第一个日期早于或等于第二个日期。
输出
对于每组数据输出一行,形如"Case #X: Y"。X为数据组数,从1开始,Y为答案。
数据范围
1 ≤ T ≤ 550
小数据:
2000 ≤ year ≤ 3000
大数据:
2000 ≤ year ≤ 2×109
样例输入
4
January 12, 2012
March 19, 2012
August 12, 2899
August 12, 2901
August 12, 2000
August 12, 2005
February 29, 2004
February 29, 2012
样例输出
Case #1: 1
Case #2: 0
Case #3: 1
Case #4: 3
2.问题分析
这个问题难度不大,但需要处理的细节比较多。读完题后,第一思路就是计算起始时间和终止时间之间有多少个闰年,然后在判断边界条件。按照这个思路解题,实现起来需要处理的细节不较多 。
为了使问题更加简单,我们可以找一个公共的“起始时间”,比如0年0月0日(ST)。然后分别计算出题目给出的两个时间与ST之间有多少个2月29日,两者的差就是所求问题的解。有一个细节就是,题目给出的第一个时间如果是闰年2月29日,作差后需要加1.
3.代码
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <cmath> 5 #include <map> 6 #include <fstream> 7 using namespace std; 8 9 string firstmonth,secondmonth; 10 int firstday,secondday; 11 int firstyear,secondyear; 12 map<string,int> myMonth; 13 14 int total(string month,int day,int year); 15 bool isIncludeRun(string month,int day,int year); 16 int main() 17 { 18 int T; 19 int i,j; 20 myMonth.insert(pair<string,int>("January",1)); 21 myMonth.insert(pair<string,int>("February",2)); 22 myMonth.insert(pair<string,int>("March",3)); 23 myMonth.insert(pair<string,int>("April",4)); 24 myMonth.insert(pair<string,int>("May",5)); 25 myMonth.insert(pair<string,int>("June",6)); 26 myMonth.insert(pair<string,int>("July",7)); 27 myMonth.insert(pair<string,int>("August",8)); 28 myMonth.insert(pair<string,int>("September",9)); 29 myMonth.insert(pair<string,int>("October",10)); 30 myMonth.insert(pair<string,int>("November",11)); 31 myMonth.insert(pair<string,int>("December",12)); 32 cin >> T; 33 char c1,c2; 34 int count1,count2,count; 35 for (i=1;i<=T;i++) 36 { 37 cin >> firstmonth >> firstday>>c1 >> firstyear>>secondmonth >> secondday >>c2>> secondyear; 38 count1 = total(firstmonth,firstday,firstyear); 39 count2 = total(secondmonth,secondday,secondyear); 40 count = count2 - count1; 41 if (isIncludeRun(firstmonth,firstday,firstyear))//判断第一个时间是不是闰年的2.29 42 { 43 count++; 44 } 45 cout<< "Case #"<<i<<": " <<count<<endl; 46 //rs.push_back(run()); 47 } 48 49 50 return 0; 51 } 52 53 int total(string month,int day,int year) 54 { 55 int res=0; 56 res +=(year/4-year/100+year/400);//这里统计有多少个闰年时,其实是计算0.0.0到year这年的最后一天12.31之间的闰年天数 57 if (0 == year%400) 58 { 59 int temp =(myMonth.find(month))->second; 60 if ((temp == 2 && day==29)||temp>2) 61 { 62 } 63 else 64 res--; 65 } 66 67 if (0 != year%100 && 0==year%4) 68 { 69 int temp =(myMonth.find(month))->second; 70 if ((temp == 2 && day==29)||temp>2) 71 { 72 } 73 else 74 res--; 75 } 76 return res; 77 } 78 79 bool isIncludeRun(string month,int day,int year) 80 { 81 if (0 == year%400) 82 { 83 int temp =(myMonth.find(month))->second; 84 if ((temp == 2 && day==29)) 85 { 86 return true; 87 } 88 } 89 90 if (0 != year%100 && 0==year%4) 91 { 92 int temp =(myMonth.find(month))->second; 93 if ((temp == 2 && day==29)) 94 { 95 return true; 96 } 97 } 98 99 return false; 100 }
ok。