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。