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

題目鏈接:#1148 : 2月29日

時間限制: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<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容斥的時候,有差錯(可以慢慢想想)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章