题目内容:
某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月6日,所以超过200岁的生日和未出生的生日都是不合理的,应该被过滤掉。
输入格式:
输入在第一行给出正整数N,取值在 (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
思路分析:
本题思路是记录输入数据的时候直接剔除无效数字,并记录有效数据个数,对有效数据排序之后,输出“最年长”和“最年轻”的数据。
注意点是输出时考虑只有一个有效数据,以及没有有效数据的情况。
代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct birth_{
char name[6];
int yr, mon, day;
}bir;
int comp(const void* a, const void *b) // 比较函数
{
bir *c = (bir*)a, *d = (bir*)b;
if (c->yr != d->yr) return c->yr - d->yr;
else if (c->mon != d->mon) return c->mon - d->mon;
else return c->day - d->day;
}
int main()
{
int i = 0, n;
scanf("%d", &n);
bir fo[n], t = {"top", 2014, 9, 6}, b = {"btm", 1814, 9, 6}; // 设定有效信息的边界
for (int j = 0; j < n; j++) {
scanf("%s %d/%d/%d", fo[i].name, &fo[i].yr, &fo[i].mon, &fo[i].day );
if (comp(&fo[i], &t) > 0 || comp(&fo[i], &b) < 0) continue; // 当大于上界或者小于下界时,无效
i++;
}
qsort(fo, i, sizeof(bir), comp);
if (i > 1)
printf("%d %s %s", i, fo[0].name, fo[i-1].name);
else if (i == 1)
printf("1 %s %s", fo[0].name, fo[0].name);
else
printf("0");
return 0;
}