1028 人口普查 (20分)

题目

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式

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

输出格式

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

输入样例

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出样例

3 Tom John

题干分析

  1. 生日在1814年9月6日之前(不包括9月6日),生日在2014年9月6日之后(不包括9月6日)为不合理的生日。

陷阱

  1. 合理的生日可能为0个,此时不应有最大年龄和最小年龄。

解题思路

通过结构体来保存生日信息。在读入信息的过程中,过滤掉不合理的生日,将合理的生日保存在结构体数组中,同时可以通过最终的下标,得知合理的生日数。再遍历一次结构体数组,得到最大生日和最小生日信息。

代码

#include <stdio.h>
#include <stdlib.h>
typedef struct birth
{
    char name[6];
    int year;
    int month;
    int day;
}birth;
int main()
{
    int N;
    if(scanf("%d",&N)==1)
    {
        birth *man=(birth *)malloc(sizeof(birth)*N);
        int j=0;		//j用来记录合理的生日记录
        for(int i=0;i<N;i++)		//在录入生日信息的同时,过滤掉不合理的生日
        {
            scanf("%s %d/%d/%d",man[j].name,&man[j].year,&man[j].month,&man[j].day);
            if(man[j].year<1814)		//生日在1814.9.6之前
                continue;
            else if(man[j].year==1814)
            {
              if(man[j].month<9)
                    continue;
              else if(man[j].month==9)
                if(man[j].day<6)
                    continue;
            }
            if(man[j].year>2014)		//生日在2014.9.6之后
                continue;
            else if(man[j].year==2014)
            {
              if(man[j].month>9)
                continue;
              else if(man[j].month==9)
                if(man[j].day>6)
                    continue;
            }
            j++;		//如果生日合理,则在下一个数组空间写入新的信息
        }
        int max=0,min=0;			//最大生日和最小生日者的下标
        for(int i=1;i<j;i++)		//按顺序比较,同时获得最大生日和最小生日者的下标
        {
            if(man[i].year<man[max].year)
                max=i;
            else if(man[i].year==man[max].year)
            {
                if(man[i].month<man[max].month)
                    max=i;
                else if(man[i].month==man[max].month)
                    if(man[i].day<man[max].day)
                        max=i;
            }

            if(man[i].year>man[min].year)
                min=i;
            else if(man[i].year==man[min].year)
            {
                if(man[i].month>man[min].month)
                    min=i;
                else if(man[i].month==man[min].month)
                    if(man[i].day>man[min].day)
                        min=i;
            }
        }
        if(j>0)		//如果有合理的生日,才按照样例中格式输出
            printf("%d %s %s",j,man[max].name,man[min].name);
        else
            printf("0");

    }
    return 0;
}

结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值