1028. 人口普查(20)
题目:
某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过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
注意:如果没有有效生日日期,应输出‘0’ (感觉这里挺坑的。。。)
友情提示:如果你和我一样,对于出生日期和年龄之间的关系傻傻分不清的话,那么。。。请像我一样在写程序之前狂敲一下思路,免得写着写着就犯傻了。。。
思路:
* 判断出生日期是否合法
* ……..if(合法)
* ……..对比出生日期:
* …………….找最大:出生日期越小–>出生早–>年龄大
* …………….找最小:出生日期越大–>出生晚–>年龄小
*
* Tip: 便捷的方法是:
* …….. [ 直接将用户的出生”年/月/日“直接看作一个字符串 ]
* 判断是否合法: if( 200年前日期 < 用户生日字符串 < 今天日期) 生日合法
* 对比生日大小:
* …….. if(用户A生日 ”早于“ 最大年龄者生日) 用户A为最大年龄者
* …….. if(用户B生日 ”晚于“ 最小年龄者生日) 用户B为最小年龄者
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OLD "1814/09/06"//年龄最大的生日上界
#define YOUNG "2014/09/06"//年龄最小的生日下界
#define SIZE_NAME 6//名字长度+1
#define SIZE_BIR 11//生日字符串长度+1
typedef struct{
char name[SIZE_NAME];
char birth[SIZE_BIR];
}AGE;
int main(void)
{
int N,countValid;
AGE data,max,min;//max表示最大年龄者,min表示最小年龄者
scanf("%d",&N);
countValid = 0;
char maxBirth[SIZE_BIR],minBirth[SIZE_BIR];//最大年龄者”生日“和最小年龄者”生日“
strcpy(maxBirth,YOUNG);
strcpy(minBirth,OLD);
for(int i = 0; i < N; i++ )
{
int isValid = 0;
scanf("%s %s",data.name,data.birth);
//判断是否合法
if( strcmp(data.birth,OLD) >= 0 && strcmp(data.birth,YOUNG) <= 0 )
isValid = 1;
//如果生日合法
if(isValid)
{
countValid++;//计算有效数据数量
//找年龄最大者(生日日期< max的生日 -->出生更早,年龄更大)
if(strcmp(data.birth,maxBirth) < 0)
{
strcpy(maxBirth,data.birth);
max = data;
}
//找年龄最小者(生日日期 > min的生日 -->出生更晚,年龄更小)
if(strcmp(data.birth,minBirth) > 0)
{
strcpy(minBirth,data.birth);
min = data;
}
}
}
//输出
if( !countValid )//如果没有有效生日日期,输出'0'
printf("0\n");
else
printf("%d %s %s\n",countValid,max.name,min.name);
return 0;
}
小结:
如何看待“输入”对一个程序至关重要。 程序开始的时候,最首先的考虑应该是:要以什么形式储存数据。不同的数据储存方式通常造就截然不同的算法,因此花点时间考虑“数据结构”绝对是值得的。 乙级中并没有涉及什么高级数据结构,所以通常就是在字符串/单字符/数值(包括整型/浮点型)/数组/结构/指针之间权衡即可。