HDOJ1201-18岁生日

本文介绍了一种计算从出生日期到18岁生日总天数的方法,通过判断闰年和平年,精确计算不同月份出生的人到达18岁生日所需的天数,特别考虑了2月29日出生的情况。

Problem Description

Gardon的18岁生日就要到了,他当然非常开心,但是他突然想到一个问题,是不是每一个人从出生开始。到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他想请你帮忙计算一下他和他的几个朋友从出生到达18岁生日所经过的总天数,让他好来比较一下。

Input

一个数T,后面T行每行有一个日期,格式是YYYY-MM-DD。如我的生日是1988-03-07。

Output

T行,每行一个数,表示此人从出生到18岁生日所经过的天数。假设这个人没有18岁生日,就输出-1。

Sample Input

1
1988-03-07

Sample Output

6574

解题思路:

1.先把中间17年的整年算出来,出生那年剩下的日子与十八岁那一年生日前度过的日子正好可以组成一整年。再把这一个整年进行分情况讨论,以三月份为分界线。

java代码如下:

import java.util.Scanner;
public class Main {
    //判断闰年函数
    public static boolean isRun(int year){
        if((year%400==0)||((year%4==0)&&(year%100!=0))){
            return true;
        }else {
            return false;
        }
    }
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        int y,m,d,sum=0;
        //       int[] a=new int[t];
        String str;
        sc.nextLine();//nextLine()接收上次读入产生的回车符
        // while(sc.hasNext()){
        for(int i=0;i<t;i++) {
            str = sc.nextLine();
            String[] arr = str.split("-");
            y = Integer.valueOf(arr[0]);
            m = Integer.valueOf(arr[1]);
            d = Integer.valueOf(arr[2]);
            if(isRun(y)&&m==2&&d==29){    //十八年后不是闰年,这个人没有十八岁生日
                System.out.println(-1);
            }else{
                for(int n=y+1;n<=y+17;n++){//先算中间的年数
                    if(isRun(n)){
                        sum+=366;
                    }else{
                        sum+=365;
                    }
                }
                if(isRun(y)){      //出生那年与十八岁那一年正好可以组成一整年。
                    if(m<=2){     //三月之前的生日则还需要加上二月份多出来的一天
                        sum+=366;
                    }else{       //三月之后的生日则第一年度过的日子里不包含本年多出来的一天
                        sum+=365;
                    }
                }else{
                    if(isRun(y+18)){   //第一年不是闰年
                        if(m<=2){
                            sum+=365;//三月之前的生日则第十八年度过的日子里不包含本年多出来的一天
                        }else{
                            sum+=366;//三月之后的生日则还需要加上二月份多出来的一天
                        }
                    }else{    //第一年和第十八年都不是闰年
                        sum+=365;
                    }
                }
                System.out.println(sum);
                sum=0;
            }

        }
        //}
    }
}

进行测试结果如下:

7
1600-02-28
6575
1600-06-06
6574
1582-02-28
6574
1582-06-06
6575
1581-02-28
6574
1581-06-06
6574
1600-02-29
-1

Process finished with exit code 0

OJ显示通过

2.更为优雅的思路和代码

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n;
        String str;
        n=sc.nextInt();
        sc.nextLine();
        while(n--!=0) {   //接收n次输入结果
            str=sc.nextLine();
            String[] strs=str.split("-");
            int y = Integer.parseInt(strs[0]);
            int m = Integer.parseInt(strs[1]);
            int d = Integer.parseInt(strs[2]);
            int year=y+18;
            int days=0;
            if(m==2 && d==29 && leapyear(year)!=1) {//十八年后不是闰年一定没有十八岁生日
                System.out.println(-1);
            }else {
                days=365*18;        //事先都按照平年求
                for(int i=y+1; i<year; i++) {
                    days+=leapyear(i);//中间的年份若为闰年把各自产生的多余一天再加上
                }
                if(m>2) {       //若为三月及以后只需要判断十八岁那年是否产生多余天数
                    days+=leapyear(year); //18岁那年的闰年天数
                }else {//若为一月或者二月只需要判断出生那年是否产生多余天数
                    days+=leapyear(y);    //出生年闰年天数
                }
                System.out.println(days);
            }

        }

    }
    public static int leapyear(int y) {
        if((y%4 == 0 && y%100 != 0) || y%400 == 0)
            return 1;
        return 0;

    }
}

输出结果如下:

7
1600-02-28
6575
1600-06-06
6574
1582-02-28
6574
1582-06-06
6575
1581-02-28
6574
1581-06-06
6574
1600-02-29
-1

Process finished with exit code 0

OJ显示通过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值