题目:
时间限制:2000ms
单点时限:1000ms
内存限制:256MB
描述
给定两个日期,计算这两个日期之间有多少个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月29,再加上中间闰年数目。
我的答案:
#include <iostream> #include <string> #include <stdio.h> #include <memory> #include <string.h> using namespace std; string m[]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"}; class YEAR{ public : int year; string mouth; int day; int i_mouth; int special; void tran_mouth(){ for(int i=0;i<12;i++) if(mouth==m[i]) i_mouth=i+1; }; void cal(){ special=year/4-year/100+year/400; }; bool is_special(){ if(year%400==0||(year%4==0&&year%100!=0)){ return true; } return false; }; bool before_include_special(){ if(i_mouth<2||(i_mouth==2&&day<=29)) return true; else return false; }; bool before_special(){ if(i_mouth<2||(i_mouth==2&&day<29)) return true; else return false; }; }; int main(){ int T; int Case=0; cin>>T; while(T--){ char t; Case++; YEAR start; YEAR end; cin>>start.mouth; cin>>start.day; cin>>t; cin>>start.year; cin>>end.mouth; cin>> end.day; cin>> t; cin>> end.year; start.tran_mouth(); start.cal(); end.tran_mouth(); end.cal(); int ans= end.special- start.special; if(start.is_special()&&start.before_include_special()){ ans+=1; } if(end.is_special()&&end.before_special()){ ans-=1; } cout<<"Case #"<<Case<<": "<<ans<<endl; } }
最优答案:
#include <iostream> #include <cstdio> #include <string> #include <map> #include <algorithm> using namespace std; #define mxn 200005 #define LL long long #define MP make_pair #define REP(i, a, b) for (int i = a; i <= b; ++i) #define FOR(i, a, b) for (int i = a; i < b; ++i) string s[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"}; map<string, int> mp; void init() { FOR(i, 0, 12) mp[s[i]] = i + 1; } int cal(int y, int m, int d) { int ret = y / 4 - y / 100 + y / 400; if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) if (m == 1 || m == 2 && d < 29) --ret; return ret; } int main() { init(); int d, y, cas = 0, t; char ss[100]; scanf("%d", &t); while (t--) { scanf("%s %d, %d", ss, &d, &y); int ans = 0; ans -= cal(y, mp[ss], d); if (y % 400 == 0 || y % 4 == 0 && y % 100 != 0) if (mp[ss] == 2 && d == 29) ++ans; scanf("%s %d, %d", ss, &d, &y); ans += cal(y, mp[ss], d); printf("Case #%d: %d ", ++cas, ans); } return 0; }