「PAT乙级真题解析」Basic Level 1028 人口普查 (问题分析+完整步骤+伪代码描述+提交通过代码)

题目给定一堆生日, 要求输出最年长和最年轻的人. 同时说明时间有不合理的数据, 需要排除掉超过200岁和未出生的生日. 今天的日期是2014年9月6日.

#算法#pat考试#数据结构#c语言#需求分析

Table of Contents

乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范。从小白开始逐步掌握用编程解决问题。

PAT乙级BasicLevelPractice 1028

问题分析:

题目给定一堆生日, 要求输出最年长和最年轻的人. 同时说明时间有不合理的数据, 需要排除掉超过200岁和未出生的生日. 今天的日期是2014年9月6日.

所以, 题目可以描述为: 给定一些生日信息, 排除掉日期大于2014/09/06的日期, 以及小于1814/09/06的日期。 找出剩下的日期里最大的日期和最小的日期. 输出剩下的日期的个数, 生日最大的人的姓名, 生日最小的人的姓名

如何比较日期大小

首先比较年份大小, 如果年份相同, 比较月份大小 如果月份也相同, 比如日期大小 比较过程在不同编程语言中实现有所不同

完整描述步骤

  1. 获取输入: 生日数据个数, 详情的生日日期
  2. 过滤掉不在合理范围的生日
  3. 对于每个日期, 检查是否是最大的日期或者是最小的日期. 统计当前最大最小的日期和对应的人名
  4. 输出合理范围的生日个数, 生日最大的人名, 生日最小的人名

伪代码描述

  1. get input birthday_amount
  2. init reasonable_amount = 0, max_birthday_name = "", min_birthday_name = ""
  3. for (int i = 0; i < birthday_amount; i++): get input name, birdthday if not brithday_is_reasonable: continue; reasonable_amount++; if brithday_is_max: max_birthday_name = name if brithday_is_min: min_birthday_name = name
  4. print(reasonable_amount, max_birthday_name, min_birthday_name)

完整提交代码

/*
# 问题分析:
题目给定一堆生日, 要求输出最年长和最年轻的人. 
同时说明时间有不合理的数据, 需要排除掉超过200岁和未出生的生日.
今天的日期是2014年9月6日.
 
所以, 题目可以描述为:
给定一些生日信息, 排除掉日期大于2014/09/06的日期, 以及小于1814/09/06的日期。
找出剩下的日期里最大的日期和最小的日期.
输出剩下的日期的个数, 生日最大的人的姓名, 生日最小的人的姓名
 
## 如何比较日期大小
首先比较年份大小,
如果年份相同, 比较月份大小
如果月份也相同, 比如日期大小
**比较过程在不同编程语言中实现有所不同**
 
# 完整描述步骤
1. 获取输入: 生日数据个数, 详情的生日日期
2. 过滤掉不在合理范围的生日
3. 对于每个日期, 检查是否是最大的日期或者是最小的日期. 统计当前最大最小的日期和对应的人名
4. 输出合理范围的生日个数, 生日最大的人名, 生日最小的人名
 
# 伪代码描述
1. get input birthday_amount
2. init reasonable_amount = 0, max_birthday_name = "", min_birthday_name = ""
3. for (int i = 0; i < birthday_amount; i++):
    get input name, birdthday
    if not brithday_is_reasonable:
        continue;
    reasonable_amount++;
    if brithday_is_max:
        max_birthday_name = name
    if brithday_is_min:
        min_birthday_name = name
4. print(reasonable_amount, max_birthday_name, min_birthday_name)
*/
 
# include<stdio.h>
# include<string.h>
 
int main(){
    char max_birthday[11];
    char person_name_with_max_birthday[6] = "1814/09/06";
    char min_birthday[11];
    char person_name_with_min_birthday[6] = "2014/09/06";
    int case_amount;
    scanf("%d\n", &case_amount);
    
    char name[6];
    char birthday[11];
    int reasonable_amount = 0;
    for (int i = 0; i < case_amount; i++){
        scanf("%s %s\n", name, birthday);
        int later_than_today = strcmp("2014/09/06", birthday) < 0;
        int more_than_200_years_old = strcmp("1814/09/06", birthday) > 0;
        if (later_than_today || more_than_200_years_old)
            continue;
        
        reasonable_amount++;
        if (strcmp(max_birthday, birthday) <= 0){
            strcpy(max_birthday, birthday);
            strcpy(person_name_with_max_birthday, name);
        } 
        if (strcmp(min_birthday, birthday) >= 0){
            strcpy(min_birthday, birthday);
            strcpy(person_name_with_min_birthday, name);
        }
        
    }
    if (reasonable_amount > 0)
        printf("%d %s %s\n", reasonable_amount, person_name_with_min_birthday, person_name_with_max_birthday);
    else
        printf("0\n");
    return 0;
}
「PAT乙级真题解析」Basic Level 1028 人口普查 (问题分析+完整步骤+伪代码描述+提交通过代码) | 生活糖果