生日
1 条题解
-
0
P4618 生日(基础)
解题思路
按年龄从大到小给同学排队,可以巧妙地转化成"按出生日期从早到晚排序"。分四步做。
第一步,把问题转化一下。 年龄大的人,出生日期一定更早。所以"年龄从大到小"就等价于"出生日期从早到晚"。比如 2013 年出生的小朋友一定比 2012 年出生的小,这个道理大家都懂。出生日期有年、月、日三部分,比较时先比年份,年份相同比月份,年月都相同再比日期。
第二步,用结构体保存信息。 结构体 Birthday 保存姓名、出生年、出生月、出生日。姓名是字符串,用字符数组存。
第三步,写比较函数一层层比。 比较函数里按"年、月、日"的优先级判断:年份不同就按年份小的排前面;年份相同看月份,月份小的靠前;年月都相同看日期,日期小的靠前。排出来的顺序正好是出生日期从早到晚,也就是年龄从大到小。
第四步,用例子验证并输出。 用生活经验来想:同样是 2012 年出生,8 月的小朋友比 9 月的大;都是 9 月,26 号出生的又比 29 号的大。样例里 lili(2012 年 8 月 26 日)最大排第一,qiqi(2012 年 9 月 26 日)第二,yaya(2012 年 9 月 29 日)最后。题目保证年份在 1990 到 2022 之间、日期真实存在,也保证没有两个同学生日相同,所以直接读入、排序、输出姓名即可。
**回顾总结。**比较日期就像查字典,先看年、再看月、最后看日,一层一层来,绝不跨层比较。把"年龄从大到小"翻译成"日期从小到大",问题就变成最常见的结构体排序。注意样例里三个同学同年,所以比月份和日期就够用了。
参考代码
// 生日:按出生日期从早到晚排序(年龄从大到小),输出姓名 #include <iostream> #include <algorithm> using namespace std; // 保存一名同学的姓名和出生日期 struct Birthday { char name[30]; // 姓名 int year; // 出生年 int month; // 出生月 int day; // 出生日 }; // 自定义比较函数:出生日期早的(年龄大的)排前面 bool cmp(const Birthday &a, const Birthday &b) { if (a.year != b.year) return a.year < b.year; if (a.month != b.month) return a.month < b.month; return a.day < b.day; } int main() { int n; Birthday stu[105]; cin >> n; for (int i = 0; i < n; i++) { cin >> stu[i].name >> stu[i].year >> stu[i].month >> stu[i].day; } sort(stu, stu + n, cmp); // 年龄大的(生日早的)在前 for (int i = 0; i < n; i++) { cout << stu[i].name << endl; } return 0; }复杂度分析
sort() 排序的时间复杂度是 O(n log n),n 是小组人数(1 < n < 100)。每个结构体存姓名和一个日期,空间复杂度是 O(n)。数据规模小,程序运行极快。
- 1