首页 > 代码库 > hdu_1201 18岁生日

hdu_1201 18岁生日

http://acm.hdu.edu.cn/showproblem.php?pid=1201


分析:

        看到题目时,纠结了一会儿——出生那一年算不算一岁?  不算的。   1900.3-1901.3 才是一岁,是个时间间隔

      (主要是因为这里是按生日来算年龄,而有些题是按年份来说而非生日,这两者还是有些区别)


        1.   闰年判断

              整除4不整除100    或者   整除400

             之前觉得这两个条件搞不清楚,闰年不是每四年一个吗?

             每4年有个闰年 —— 不严谨

             应是四年一闰,百年不闰,四百年再闰 

             原因:

         地球绕太阳运行周期为365天5小时48分46秒(合365.24219天)即一回归年(tropical year)。公历的平年只有365日,比回归年短约0.2422 日,所余下的时间约为       四年累计一天,故四年于2月加1天,使当年的历年长度为366日,这一年就为闰年。
         但是,上面算法又有了一个问题。就是0.2422*4=0.9688,比一天还差0.0322天,每4年差0.0322天不算多,但每400年就会差了约3天。即是说,假如每4年一个闰年,      那么每400年就会有100个闰年,然后会多算了3天。
         所以,就规定了每四百年中要减少三个闰年。公历年份是整百数的,必须是400的倍数的才是闰年,不是400的倍数的,虽然是100的倍数,也是平年。

         2.  输入格式1900-3-18

              scanf("%d-%d-%d", &n, &y, &r);


//hud 1201
#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>
using namespace std;

bool leap(int n)
{
    return (n%4==0 && n%100!=0) || (n%400==0);
}

int main()
{
    int t;
    int n,y,r;
    int cnt;
    scanf("%d",&t);
    while(t--){
        cnt=0;
        scanf("%d-%d-%d",&n,&y,&r);
        //cout<<n<<" "<<y<<" "<<r<<endl;
        if(leap(n) && y==2 && r==29 && !leap(n+18)){
           printf("-1\n");
           continue;
        }

        for(int i=0;i<=18;i++)
            if(leap(n+i)) cnt++;
        if(leap(n) && y>2 )   cnt--;    //如果出生那年已经过了2月则要减去多加的一天
        if(leap(n+18) && y<2) cnt--;    //如果18岁那年没过2月也要减去多加的一天 
        printf("%d\n",365*18+cnt);
    }
    return 0;
}