人口普查--偷懒的做法反而能AC!

题目描述

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式:

输入在第一行给出正整数 N,取值在(0,105];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按 yyyy/mm/dd(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出格式:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

输入样例:

1
2
3
4
5
6
5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出样例:

1
3 Tom John

当没有合法生日时,要输出0

解答

  • 我的代码没有通过PTA最后一个测试点,但是却能在牛客网AC。

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #include <stdio.h>
    #include <string.h>

    //判断是否是闰年
    int isp(int y)
    {
    if(y%400==0||y%4==0&&y%100!=0)
    return 1;
    else
    return 0;
    }

    //给定某人出生日期,计算其总共存活天数day
    int allday(int y,int m,int d)
    {
    int month[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    //计算出生那一年所占的天数byd
    int byd=0;
    for(int j=y+1;j<=12;++j)
    {
    byd+=month[j-1];
    }
    int day=byd+month[m-1]-d;
    if(m<=2&&isp(y))
    day+=1;//闰年则加1
    //计算从出生第二年至2014年1月1号之间的天数
    for(int k=y+1;k<2014;++k)
    {
    day+=365;
    if(isp(k))
    day+=1;//闰年则加1
    }
    //计算2014年1月1号2014年9月6日之间的天数
    for(int p=1;p<=8;++p)
    {
    day+=month[p-1];
    }
    if(isp(2014))
    day+=1;//闰年则加1
    day+=6;//这便是总共的生存天数
    return day;
    }

    int main()
    {
    int n;//给定的人数
    char name[6];//名字
    int y,m,d;//出生年月日
    scanf("%d",&n);
    getchar();

    int cnt=0;//合法的生日个数
    int day=0;//总共存活天数

    int th=allday(1814,9,6);//计算两百岁的人所存活的总天数th
    //printf("200岁共%d天\n\n",th);
    char maxname[6],minname[6];//记录年龄最大和年龄最小的人的姓名
    int maxday=0,minday=th+1;//初始化年龄最大和最小的人的总共存活天数
    for(int i=0;i<n;++i)
    {
    scanf("%s %d/%d/%d",name,&y,&m,&d);
    //printf("m=%d d=%d\n",m,d);
    day=allday(y,m,d);//计算这个人的总共存活天数
    //printf("%s:%d\n",name,day);
    //合法性判断
    if(day>th)//年龄超过200岁
    {
    //printf("%s超过200岁了\n",name);
    continue;
    }

    if(y>2014||(y==2014)&&(m>9)||(y==2014)&&(m==9)&&(d>6))//此人还未出生
    {
    //printf("%s 还未出生\n",name);
    continue;
    }

    //此时合法,继续下面的操作
    ++cnt;
    if(day>maxday)
    {
    maxday=day;
    strcpy(maxname,name);
    }
    if(day<minday)
    {
    minday=day;
    strcpy(minname,name);
    }
    }
    if(cnt==0)
    printf("0");
    else
    printf("%d %s %s",cnt,maxname,minname);
    }
  • 网上的做法大部分都是将生日转化为数字来做的,不用像我那样考虑的那么复杂

    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
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    int solve(int year,int month,int day);
    int main( )
    {
    int year,month,day;
    int n,i,count=0;
    int min_age=18140905,max_age=20140907;//初始化时稍微大过范围即可
    char name[8],max_name[8],min_name[8];

    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
    scanf("%s%d/%d/%d",name,&year,&month,&day);
    int k=solve(year,month,day);
    if(k>0)//年龄在范围内
    {
    if(max_age>k)//年龄越大,日期越小
    {
    max_age=k;
    strcpy(max_name,name);//字符串复制
    }
    if(min_age<k)//年龄越小,日期越大
    {
    min_age=k;
    strcpy(min_name,name);
    }
    count++;
    }
    }

    //当合法生日为0时,只输出0,测试点3
    if(count)
    printf("%d %s %s",count,max_name,min_name);
    else
    printf("0");
    return 0;
    }
    int solve(int year,int month,int day)
    {
    //因为题目说明,输入的日期一定合理,所以可以这样算
    int e=year*10000+month*100+day;

    if(e>20140906||e<18140906)
    return -1;

    return e;
    }

    也可以这样

    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
    #include <stdio.h>
    #include <string.h>
    int number(int y, int m, int d)
    {
    return y*10000 + m*100 + d;
    }

    int main()
    {

    char temp[10], name_max[10], name_min[10];
    int y, m, d, n, count=0, x;
    int max = 18140906, min = 120140906;
    scanf("%d", &n);
    for(int i=0; i<n; ++i){
    scanf("%s %d/%d/%d", temp, &y, &m, &d);
    x = number(y, m, d);
    if(x >= 18140906 && x <= 20140906){
    count++;
    if(x > max){
    max = x;
    strcpy(name_max, temp);
    }
    if(x < min){
    min = x;
    strcpy(name_min, temp);
    }
    }
    }
    if(count == 0)
    printf("0");
    else{
    printf("%d %s %s", count,name_min, name_max );
    }
    return 0;
    }
凡希 wechat
喜欢所以热爱,坚持干货分享,欢迎订阅我的微信公众号
呐,请我吃辣条