whenever

  • Home

  • Tags21

  • Categories6

  • Archives122

  • About

PAT乙级1028 || 人口普查(详解,C/C++示例,测试点分析)

Posted on 2019-09-06 In PAT

人口普查

题目描述

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

输入格式

输入在第一行给出正整数 N,取值在(0,$10^5$];随后 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

问题解决

解题思想

分别设置最年长人和最年轻人的姓名、生日,最年长人的生日初始化为最晚的年月日,最年轻人的生日初始化为最早的年月日(想一下为什么要这样初始化?);用scanf()函数读入每一个人的姓名及生日(注意:不能用gets()函数,思考一下为什么?它们遇到空格的处理?),此处,生日以字符串的形式读入,构造一个函数将字符串格式生日转换成数值形式,通过引用来返回数值型的year,month,day;接着,判断此时输入的生日是否合理(不是年龄超过200岁的情况或未出生的生日的情况),若不合理,用continue直接跳过本次循环,进入下一次输入,若合理,判断是否比目前最年长的人更年长或者比目前最年轻的人更年轻,并进行相应的更新。

坑点提醒

本题容易忽略的一个点就是:对有效生日个数为0个的特殊情况的处理。若有效生日个数为0个则不存在最年长或最年轻的人,相应的,只需输出有效生日个数即可(0),不需要输出最年长或最年轻的人的姓名。这也是PAT在线评测系统倒数第二个测试点测试的内容,若此处处理不当则此测试点将不会通过。

代码示例(C/C++)

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
#include <cstdio>
#include <cstring>
using namespace std;
void Birth_Strtonum(int &year,int &month,int &day,char birthday[]);
int main()
{
int n;
scanf("%d",&n);
char name[6],birthday[11];//读入姓名和生日
char oldest[6],youngest[6];//最年长人和最年轻人的姓名
int old_y = 2014,old_m = 9,old_d = 6;//最年长人的生日,初始化为最晚的年月日
int young_y = 1814,young_m = 9,young_d = 6;//最年轻人的生日,初始化为最早的年月日
int coun = 0;//有效生日的个数
for(int i = 0; i < n; i++){
getchar();//吸收掉缓冲区换行符
scanf("%s%s",name,birthday);//读入名字,以字符串格式读入生日
int year,month,day;
year = month = day = 0;
Birth_Strtonum(year,month,day,birthday);
//下面条件是年龄超过200岁的情况
if(year < 1814||(year == 1814&&month <9)
||(year == 1814&&month == 9&&day < 6)){
continue;
}
//下面条件是未出生的生日的情况
if(year > 2014||(year == 2014&&month >9)
||(year == 2014&&month == 9&&day > 6)){
continue;
}
//更新最年长的人
if(year < old_y||(year == old_y&&month < old_m)
||(year == old_y&&month == old_m&&day < old_d)){
old_y = year;
old_m = month;
old_d = day;
strcpy(oldest,name);
}
//更新最年轻的人
if(year > young_y||(year == young_y&&month > young_m)
||(year == young_y&&month == young_m&&day > young_d)){
young_y = year;
young_m = month;
young_d = day;
strcpy(youngest,name);
}
coun++;//有效生日的个数
}
if(coun == 0){//若有效生日个数为0个则不存在最年长或最年轻的人
printf("%d",coun);
}
else{
printf("%d %s %s",coun,oldest,youngest);
}
return 0;
}
//字符串格式生日转换成数值形式,通过引用来返回数值型的year,month,day
void Birth_Strtonum(int &year,int &month,int &day,char birthday[])
{
int j = 0;
int k = 1000;
while(j < 4){//年份转换成数值,注意每一个字符都要转换成数字
year += (birthday[j] - '0') * k;
k /= 10;
j++;
}
j++;//跳过年与月的间隔符号'/'
month = (birthday[j] - '0') * 10 + (birthday[j + 1] - '0');//月份转换成数值
j += 3;//j跳到天的位置
day = (birthday[j] - '0') * 10 + (birthday[j + 1] - '0');//天数转换成数值
}

题目来源:PAT乙级1028
作者:CHEN, Yue
单位:浙江大学

稀罕作者
Mengzhao Wang WeChat Pay

WeChat Pay

Mengzhao Wang Alipay

Alipay

# C/C++ # PAT # 编程
PAT乙级1027 || 打印沙漏(详解,C/C++示例,测试点分析)
PAT乙级1029 || 旧键盘(详解,C/C++示例,测试点分析)
  • Table of Contents
  • Overview
Mengzhao Wang

Mengzhao Wang

Try? All the way !
122 posts
6 categories
21 tags
  1. 1. 人口普查
    1. 1.1. 题目描述
    2. 1.2. 输入格式
    3. 1.3. 输出格式
    4. 1.4. 输入样例
    5. 1.5. 输出样例
    6. 1.6. 问题解决
      1. 1.6.1. 解题思想
      2. 1.6.2. 坑点提醒
      3. 1.6.3. 代码示例(C/C++)
© 2021 Mengzhao Wang