某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。
输入格式:
输入在第一行给出正整数 N,取值在(0,10^5 ];随后 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
题目链接:https://pintia.cn/problem-sets/994805260223102976/problems/994805293282607104
思路:注意理解好题意,在2014 年 9 月 6 日之后未出生的生日的条件之一是:年份为2014年,月份大于9月份或者是月份为9月份,但日期大于6号。
知识点考察:结构体,输入格式的处理。
以下为AC代码,供参考,相互交流学习。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct Peo
{ //结构体数组
char name[10];
int year;
int month;
int date;
}peo[maxn];
bool cmp1(Peo a,Peo b)//排序算法
{
if(a.year!=b.year)
return a.year<b.year;
else if((a.year==b.year)&&(a.month!=b.month))
return a.month<b.month;
else
return a.date<=b.date;
}
int main()
{
int n = 0;
while(scanf("%d",&n)==1)
{
memset(peo,0,sizeof(peo));
int m = n; //m记录最终合法的个数
for(int i=0;i<n;++i)
{
scanf("%s",peo[i].name);
scanf("%04d/%02d/%02d",&peo[i].year,&peo[i].month,&peo[i].date);
//printf("%d/%d/%d\n",peo[i].year,peo[i].month,peo[i].date);
if(peo[i].year>2014||peo[i].year<1814)
{
m--;
peo[i].year = 0; //标记为0
}
else if(peo[i].year==2014)
{//2014.9之后未出生的人
if(peo[i].month>9)
{
m--;
peo[i].year = 0;
}
else if((peo[i].month==9)&&(peo[i].date>6))
{
m--;
peo[i].year = 0;
}
}
else if(1814==peo[i].year)
{
if(peo[i].month<9)
{
m--;
peo[i].year = 0;
}
else if((peo[i].month==9)&&(peo[i].date<6))
{
m--;
peo[i].year = 0;
}
}
}
printf("%d",m);
if(m)
{
sort(peo,peo+n,cmp1);
int i=0;
while(peo[i].year==0)
i++; //找到第一个非0元素
printf(" %s %s",peo[i].name,peo[n-1].name);
}
printf("\n");
}
return 0;
}