PAT B1028 人口普查

题目描述


分析:

先定义结构体类型 person 来存放人的姓名、出生日期。由于题目中涉及下面四个信息,因此需要设定四个变量来存放它们:

  1. 最年长的人,需要根据输入不断修正,因此不妨设 person 型 oldest 来存放它,初始化出生日期为 2014 年 9 月 6 日。
  2. 最年轻的人,需要根据输入不断修正,因此不妨设 person 型 youngest 来存放它,初始化出生日期为 1814 年 9 月 6 日。
  3. 合法日期的左边界 1814 年 9 月 6 日在程序中固定不变,因此不妨设置 person 型 left 来存放它,初始化日期为 1814 年 9 月 6 日。
  4. 合法日期的右边界 2014 年 9 月 6 日在程序中固定不变,因此不妨设置 person 型 right 来存放它,初始化日期为 2014 年 9 月 6 日。

程序的基本思路是在读入该日期时判断该日期是否在合法日期的区间内。如果在,就使其更新最年长的人的出生日期和最年轻的人的出生日期。由于本题需要许多比较判断操作,不妨写两个比较函数 less(person a, person b) 和 more(person a, person b),用来比较 a 与 b 的日期。

本题需要注意的一点是可能存在所有人的区间都不在合法区间内的情况,这时必须特判输出 0。否则会因后面多输出空格而返回“格式错误”。


代码(C++)

/*
本题中进行比较时都是比较的字面值,而不是其背后表示的年龄
比如:2000(年) < 2020(年),但 2000年出生的人的年龄是 > 2020年出生的人的年龄
*/
#include <iostream>

using namespace std;

struct Person
{
    char name[10];
    int year, month, day; // 年 月 日
} oldest, youngest, Left, Right;

void init() // 将最年长、最年轻以及合法年龄区间初始化为正确的年月日
{
    oldest.year = 2014, oldest.month = 9, oldest.day = 6;
    youngest.year = 1814, youngest.month = 9, youngest.day = 6;
    
    Left.year = 1814, Left.month = 9, Left.day = 6;
    Right.year = 2014, Right.month = 9, Right.day = 6;
}

bool Less(Person a, Person b)
{
    if (a.year != b.year) return a.year <= b.year;
    else if (a.month != b.month) return a.month <= b.month;
    else return a.day <= b.day;
}

bool More(Person a, Person b)
{
    if (a.year != b.year) return a.year >= b.year;
    else if (a.month != b.month) return a.month >= b.month;
    else return a.day >= b.day;
}

int main()
{
    init();
    
    int n, num = 0;
    scanf("%d", &n);
    
    Person tmp;
    for (int i = 0 ; i < n; i ++)
    {
        scanf("%s %d/%d/%d", tmp.name, &tmp.year, &tmp.month, &tmp.day);
        if (More(tmp, Left) && Less(tmp, Right)) // 日期合法
        {
            num ++;
            if (Less(tmp, oldest)) oldest = tmp; // 更新最年长者
            if (More(tmp, youngest)) youngest = tmp;    // 更新最年轻者
        }
    }
    
    if (num == 0) printf("%d\n", num);
    else printf("%d %s %s\n", num, oldest.name, youngest.name);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值