hihocoder#1148 : 2月29日(容斥原理,有坑)

xiaoxiao2021-02-28  21

题目链接:#1148 : 2月29日

时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期)。

只有闰年有2月29日,满足以下一个条件的年份为闰年:

年份能被4整除但不能被100整除

年份能被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<stdio.h> #include<string.h> #include<string> #include<map> #include<algorithm> using namespace std; char m1[20],m2[20]; int d1,d2,yy,y2; int main() { map<string,int>ma; ma.clear(); ma["January"]=1; ma["February"]=2; ma["March"]=3; ma["April"]=4; ma["May"]=5; ma["June"]=6; ma["July"]=7; ma["August"]=8; ma["September"]=9; ma["October"]=10; ma["November"]=11; ma["December"]=12; int t,tt=1; scanf("%d",&t); while(t--) { memset(m1,0,sizeof(m1)); memset(m2,0,sizeof(m2)); scanf("%s %d, %d",m1,&d1,&yy); scanf("%s %d, %d",m2,&d2,&y2); int ans=0; if(ma[m1]<=2)//yy这一年的2月29在区间内,是不是闰年都行 yy--; ans-=(yy/4-yy/100+yy/400); if(ma[m2]==1||(ma[m2]==2&&d2<29))//yy这一年的2月29在区间之外,是不是闰年都行 y2--; ans+=y2/4-y2/100+y2/400; printf("Case #%d: %d\n",tt++,ans); } return 0; }

写给自己的: 当初的思路是一样的,但是写错了(一直以为是正确的,代码的执行与自己想的不一样),也是用容斥原理,但是开头判断错了,开头我是记录,如果yy的2月29不在区间内,就ans–,然后再yy–,但是这样在容斥的时候,会在y2容斥的时候,有差错(可以慢慢想想)。

转载请注明原文地址: https://www.6miu.com/read-2500268.html

最新回复(0)