概述
个人主页:mzwang.top
人口普查
题目描述:
某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。输入格式:
输入在第一行给出正整数 N,取值在(0, 1 0 5 10^5 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
题目来源:PAT乙级1028
作者:CHEN, Yue
单位:浙江大学
问题解决:
解题思想
分别设置最年长人和最年轻人的姓名、生日,最年长人的生日初始化为最晚的年月日,最年轻人的生日初始化为最早的年月日(想一下为什么要这样初始化?);用scanf()函数读入每一个人的姓名及生日(注意:不能用gets()函数,思考一下为什么?它们遇到空格的处理?),此处,生日以字符串的形式读入,构造一个函数将字符串格式生日转换成数值形式,通过引用来返回数值型的year,month,day;接着,判断此时输入的生日是否合理(不是年龄超过200岁的情况或未出生的生日的情况),若不合理,用continue直接跳过本次循环,进入下一次输入,若合理,判断是否比目前最年长的人更年长或者比目前最年轻的人更年轻,并进行相应的更新。
坑点提醒
本题容易忽略的一个点就是:对有效生日个数为0个的特殊情况的处理。若有效生日个数为0个则不存在最年长或最年轻的人,相应的,只需输出有效生日个数即可(0),不需要输出最年长或最年轻的人的姓名。这也是PAT在线评测系统倒数第二个测试点测试的内容,若此处处理不当则此测试点将不会通过。
代码示例(C/C++)
小提示:请将以下代码保存为.cpp
格式(C++程序)左右滑动代码以查看完整代码
#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 || 人口普查(详解,C/C++示例,测试点分析)人口普查的全部内容,希望文章能够帮你解决PAT乙级真题1028 || 人口普查(详解,C/C++示例,测试点分析)人口普查所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复