https://vjudge.net/problem/HD...ios
一句話題意:給定出生日期(格式爲
1988-03-07
),求到18歲生日爲止經歷了多少天;沒有18歲生日輸出-1。算法
這個題目太普通了,相似的問題可能滿大街都是。這不是一個算法競賽等級的題目,可是仍是有的好說。我要記錄的是我作這題的思考方式。函數
解:spa
首先考慮閏年。通常來講,公元閏年的肯定方法以下:年份若爲400的正整倍數
時,閏;不然,年份是4的正整倍數
且不是100的正整倍數
時,閏;都不符合,平。這點體如今函數is_leap
裏。.net
我發現,若今年是閏年,日期在2月29日以前或以後的兩種情形到「明年今日」的天數是不一樣的。如2008-03-01
到2009-03-01
經歷366
天,2008-02-28
到2009-02-28
經歷365
天。code
對稱地,若今年是平年,明年是閏年也有相似的規律可說。ci
這就是我要記錄的「局部分離思想」。這個問題一開始看很複雜,可是咱們發現,這一年到下一年,無非只有3種大情形。日期在2月29日以前簡記爲「前」;日期在這以後(含)簡記爲「後」。列表以下。get
平=>平
前365天;後365天string
平=>閏
前365天;後366天it
閏=>平
前366天;後365天
這樣一來,問題就迎刃而解了。
代碼以下。
//AC,0ms; #ifdef LOCAL #include<ctime> #endif #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<sstream> #include<algorithm> #include<iostream> #include<vector> #include<set> #include<map> #define LL long long using namespace std; int is_leap(int a){ if(a%100 == 0) return !(a%400); else return !(a%4); } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); clock_t start, end; start = clock(); #endif int t; cin >> t; string s; while(t--){ int y,m,d,modify=0,after=1; cin >> y >> m >> d; m=-m; d=-d; if(m == 2 && d == 29){ cout << -1 << endl; continue; }else if(m<=2 && d<=28) after = 0; for(int i = y;i<=y+17;i++){ if(is_leap(i)){ if(!after){ modify++; } }else{ if(is_leap(i+1)){ if(after){ modify++; } } } } cout << modify + 365*18 << endl; } #ifdef LOCAL end = clock(); cout << "*************************" << endl; cout<< "Computing time: "<<(double)(end - start)*1000 / CLOCKS_PER_SEC<<"ms"<<endl; #endif return 0; }
我這裏採用了增量的形式,在18*365
天的基礎上加上多出來的那幾天。爲啥只取到y+17
呢?由於咱們只用考慮這一年變到下一年的情形。第18年不會再變到下一年,因此只計算到y+17
爲止。