某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 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
C语言实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Info {
char name[6];
int year, month, day;
};
// 比较函数,先比年份,年份相同比月份,月份相同比日期
int cmp(void *p1, void *p2) {
struct Info *info1 = (struct Info *)(p1);
struct Info *info2 = (struct Info *)(p2);
int delta_y = info1->year - info2->year;
int delta_m = info1->month - info2->month;
int delta_d = info1->day - info2->day;
if (delta_y) {
return delta_y;
} else if (delta_m) {
return delta_m;
} else {
return delta_d;
}
}
int main() {
// 输入个数
int cnt = 0;
scanf("%d", &cnt);
// 人口信息数组
struct Info info[cnt];
char names[cnt][6];
for (int i = 0; i < cnt; ++i) {
scanf("%s %d/%d/%d", &info[i].name, &info[i].year, &info[i].month, &info[i].day);
}
// 按年份排序
qsort(info, cnt, sizeof(struct Info), cmp);
int cnt_valid = 0;
// 两个临界参考时间点
struct Info info1 = {"Died", 1814, 9, 6};
struct Info info2 = {"New", 2014, 9, 6};
for (int i = 0; i < cnt; ++i) {
// 将在1814.09.06之后到2014.09.06之间的复制到names
if (cmp(&info[i], &info1) >= 0 && cmp(&info[i], &info2) <= 0) {
strcpy(names[cnt_valid++], info[i].name);
}
}
if (cnt_valid > 0) {
printf("%d %s %s\n", cnt_valid, names[0], names[cnt_valid - 1]);
} else {
// 注意一个都不符合的情况
printf("%d\n", cnt_valid);
}
return 0;
}
思路
1.主要在于写好比较时间的函数,再用qsort对数组按时间排序,筛选在1814.09.06-2014的信息
2.注意临界情况,输入的信息可以一个都不合理,这时要输出个数0