题目
某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 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
题干分析
- 生日在1814年9月6日之前(不包括9月6日),生日在2014年9月6日之后(不包括9月6日)为不合理的生日。
陷阱
- 合理的生日可能为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;
}