PAT-B 1028. 人口普查

题目内容:

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过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;
}

点这里进入试题网页

你可能感兴趣的:(pat,乙级,简洁代码)