某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 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
思路:
此题略有难度,主要思路如下,定义struct结构体,存储每个人的名字与姓名。
struct person
{
char name[6];
int year, month, day;
};
由于有的人的日期显示超过200岁或者大于现在的日期,这些都是不合理的需要筛除。一开始我想的方法是分别将年月日进行对比:
bool judge(int year, int month, int day)//
//先比较年在不在范围
//然后比较两个特殊年份的月在不在范围
//最后比较两个特殊的年份,特殊的月份,日在不在范围
if (year > 1814 && year < 2014) return true;
else if ((year == 1814 && month>9) || (year == 2014 && month < 9))return true;
else if ((year == 1814 && month == 9 && day >= 6) || (year == 2014 && month == 9 && day <= 6))return true;
else return false;
}
后来发现后更好的方法,就是将年份月份日期进行计算,将三个数合为一个数birthday=10000year+100month+day,这样就可以直接进行比较:
struct person//定义新的结构体
{
char name[6];
int birthday;//birthday=10000year+100month+day
};
bool judge(int birthday)
{
if (birthday < 18140906 || birthday>20140906) return false;
else return true;
}
定义好筛除函数以后,首先找到第一个符合日期范围的人,将其同时设置为max与min:
int N;//总共有N行数据
cin >> N;
char name[6];
int year, month, day;//临时存放年月日
int birthday;//通过年月日计算生日的8位数字
person max, min;
int n = 0;//定义n是为了计数,看找到哪一位了
int count = 0;
while (1)
{
scanf("%s %d/%d/%d", name, &year, &month, &day);//读取第一个人的名字
birthday = year * 10000 + month * 100 + day;
n++;
if (judge(birthday))//找到一地个日期合理的人的生日
{
count++;
break;
}
if (n == N)//注意这里!一开始没有写这个if函数,导致始终有一个测试用例运行超时,后来想到是这个while函数无法跳出循环,原因是给出的所有日期都不符合要求范围
{
printf("0");//这种情况需要输出一个0
return 0;
}
}
strcpy(max.name, name);//将其存在max与min中
max.birthday = birthday;
strcpy(min.name, name);
min.birthday = birthday;
一开始这里犯了一个严重的错误,导致有一个测试用例始终显示超时,检查了很久才发现如果所有给的数据都是不符合要求的,这时候要跳出循环并输出0,不能等待一直输入。
for (int i = n; i < N; i++)//找到第一个满足条件的数据后,从后一位开始循环到最后
{
scanf("%s %d/%d/%d", name, &year, &month, &day);
birthday = year * 10000 + month * 100 + day;
if (judge(birthday))//以后一找到一个就计数
{
count++;
}
else continue;//如果没有找到继续循环
if (max.birthday>birthday)//找到满足的数据,将其与max的生日进行对比,如果max生日比这个晚,将max的生日与姓名更改为新的这个人
{
strcpy(max.name, name);
max.birthday = birthday;
}
if (min.birthday<birthday)//同上,看其与min的关系
{
strcpy(min.name, name);
min.birthday = birthday;
}
}
printf("%d %s %s", count, max.name, min.name);
return 0;
代码:人口普查
//1028 人口普查
#include<iostream>
#include<string.h>
using namespace std;
struct person
{
char name[6];
int birthday;
};
bool judge(int birthday)
{
if (birthday < 18140906 || birthday>20140906) return false;
else return true;
}
int main()
{
int N;
cin >> N;
char name[6];
int year, month, day;
int birthday;
person max, min;
int n = 0;
int count = 0;
while (1)
{
scanf("%s %d/%d/%d", name, &year, &month, &day);//读取第一个人的名字
birthday = year * 10000 + month * 100 + day;
n++;
if (judge(birthday))//找到一地个日期合理的人的生日
{
count++;
break;
}
if (n == N)
{
printf("0");
return 0;
}
}
strcpy(max.name, name);//将其存在max与min中
max.birthday = birthday;
strcpy(min.name, name);
min.birthday = birthday;
for (int i = n; i < N; i++)
{
scanf("%s %d/%d/%d", name, &year, &month, &day);
birthday = year * 10000 + month * 100 + day;
if (judge(birthday))//以后一找到一个就计数
{
count++;
}
else continue;
if (max.birthday>birthday)
{
strcpy(max.name, name);
max.birthday = birthday;
}
if (min.birthday<birthday)
{
strcpy(min.name, name);
min.birthday = birthday;
}
}
printf("%d %s %s", count, max.name, min.name);
return 0;
}
网友评论