zoey
点击国内主页可以让浏览速度加快哦 ~ !

关于HDOJ 1201题(18岁生日) 的理解(C/C++)

2019-08-10 hdoj 闰年 日期计算 小技巧
Word count: 1.1k | Reading time: 5min

    刚开始没搞懂这个没有18岁生日是什么鬼,我还以为是说到今天为止是没满18岁呢,但是天知道这个题规定的今年是哪一年啊,我也不知道这个题什么时候出的啊。 所以百度了一下 。结果是说生日恰好在2月29号,然后就在18周岁那一年是没有生日的,所以称之为没有18岁。
    原因的话很简单,如果你在2月29出生,那么他一定出生在闰年,所以该年除以4肯定整除,然后18年过后,因为18不是4的整数倍,所以18岁那一年必定不是闰年,故此没有18岁生日;反之,如果不在2月29日出生,那么,不好意思,你是辣鸡(我也是,不要怕)一定会有18岁生日的那一天。
    ps.    =2.29 + !=2.29 ==> R(实数)


    也感谢博客的思路,本来还准备老老实实地去定义一下string,然后再慢慢划分年月日呢,结果搞到一个小技巧,用一个char型装一下'-'就好了,不用费劲去划分string了,真好~

题目描述

18岁生日

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 43014 Accepted Submission(s): 13725

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

Author
Gardon

Source
Gardon-DYGG Contest 2



原题链接

More info:Question



小技巧

用一个char型装一下’-‘就好,不用费劲去定义一个string然后在慢慢划分string

1
2
3
char tmp;
int year, mon, day;
cin >> year >> tmp >> mon >> tmp >> day;

Accepted代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<iostream>
#include<string>
using namespace std;
bool isR(int year) {
if (year % 4 == 0 && year % 100 != 0 ) return true;
if (year % 100 == 0 && year % 400 == 0) return true;
return false;
}
char tmp;
int year, mon, day;
int month[12] = { 31,28,31,30,31,30,31,31,30,31,31,30 };
int main(){
int T;
cin >> T;
while (T--) {
cin >> year >> tmp >> mon >> tmp >> day;
if (mon == 2 && day == 29) cout << -1 << endl;
else {
int Cyear_left_days = -1;
//出生当年的计算
//闰年&&生日早于2.29
if (isR(year) && (mon<2||(mon==2&&day<29)) ) {
Cyear_left_days = month[mon - 1] - day;
for (int i = mon; i < 12; i++) {
Cyear_left_days += month[i];
}
Cyear_left_days++;
}
//否则
else {
Cyear_left_days = month[mon - 1] - day;
for (int i = mon; i < 12; i++) {
Cyear_left_days += month[i];
}
}
int myear=year+1;
while (myear-year < 18) {
if (isR(myear)) Cyear_left_days += 366;
else Cyear_left_days += 365;
myear++;
}
//18岁那年的计算
if (isR(myear) && mon > 2) {
for (int i = 0; i < mon-1; i ++ )
Cyear_left_days += month[i];
Cyear_left_days++;
Cyear_left_days += day;
}
else {
for (int i = 0; i < mon-1; i++)
Cyear_left_days += month[i];
Cyear_left_days += day;
}
cout << Cyear_left_days << endl;
}
}
return 0;
}



参考博客 火星十一郎

以下是 火星十一郎 老哥的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
如果出生在2月29号,那么也就说出生那一年一定是闰年,通过简单证明可得:闰年+18=非闰年
*/
#include <iostream>
using namespace std;
bool is_leap(int n)
{
if((n%4==0 && n%100!=0) || n%400==0)
return 1;
else
return 0;
}
int main()
{
int T;int year, month, day;int run=0;
char tmp;
scanf("%d", &T);
while(T--)
{
run=0;
// 先开始我还傻傻的去用string表示...麻烦...
cin >> year >> tmp >> month >> tmp >> day;
if(month==2 && day==29)
{
cout << -1 << endl;
continue;
}
if(month>=3)
{
for(int i=1; i<=18; ++i)
if(is_leap(year+i))
run++;
}
else
{
for(int i=1; i<=18; ++i)
if( is_leap(year+i-1))
run++;
}
cout << 365*18+run << endl;
}
return 0;
}






Author: Zoey

Link: https://zoey1038569979.github.io/2019/08/10/hdoj1201/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
关于HDOJ 1202题(绩点计算) 的理解(C/C++)
NextPost >
关于HDOJ 1197题(进制转换) 的理解(C/C++)
CATALOG
  1. 1. 题目描述
  2. 2. 原题链接
  3. 3. 小技巧
  4. 4. Accepted代码
  5. 5. 参考博客 火星十一郎