算法日记 | C++ 结构体
算法日记 | C 结构体实战如何优雅地处理“复杂数据”大家好。今天我们来点轻松但同样重要的基础内功——结构体 (Struct)。很多同学写代码时还在用a[100],b[100],c[100]这样散乱的数组来存数据吗一旦数据多了是不是经常搞混哪个数组对应哪个属性别慌今天我们就通过三道洛谷的经典题目P5740、P5744、P5741手把手教你如何用struct把数据“打包”管理让代码瞬间变得整洁又强大准备好了吗让我们开始今天的“打包”之旅吧 关卡一寻找“卷王”之王首先登场的是我们的热身题P5740【深基 7.例 9】最厉害的学生。 题目大意班里有 N 个同学每个人都有姓名、语文、数学、英语成绩。我们需要找出总分最高的那个“学霸”。如果有并列第一就选名单里排在最前面的那个。 为什么用结构体想象一下如果你不用结构体你可能需要开四个数组string names[1000]int chinese[1000]...如果要排序你得动其中一个数组其他三个也得跟着换位置简直是灾难现场 而有了结构体我们只需要把它们“打包”在一起。 核心代码解析// 定义结构体把相关数据绑在一起 struct student{ string name; int chinese, math, english; int score; // 总分 }; // 自定义比较函数按分数从高到低排 bool f(const student a, const student b){ return a.score b.score; } int main(){ vectorstudent s; int n; cin n; while(n--){ student temp; cin temp.name temp.chinese temp.math temp.english; temp.score temp.chinese temp.math temp.english; // 算出总分 s.push_back(temp); } // 关键点使用 stable_sort 保持相对顺序 stable_sort(s.begin(), s.end(), f); // 输出第一名 cout s.begin()-name s.begin()-chinese s.begin()-math s.begin()-english endl; return0; } 避坑指南注意看这里我用的是stable_sort而不是普通的sort。题目要求“如果总分相同输出靠前的那位”。普通的sort可能会打乱原本输入的顺序而stable_sort能保证在分数相同时先输入的依然排在前面。这就是细节决定成败 关卡二培训机构的“成长”记录搞定了排序我们来看看数据的动态变化。第二题是P5744【深基 7.习 9】培训。 题目大意有一批学员参加培训经过一年后每个人都长了一岁年龄 1。NOIP 成绩提高了 20%但是满分 600不能超过哦。我们需要输入原来的信息输出培训后的新信息。 核心考点结构体的遍历与计算这道题不需要复杂的排序重点在于如何优雅地处理每一个学生的数据更新。看看我的解法我使用了迭代器Iterator来遍历整个班级for(vectorstudent::iterator it s.begin(); it ! s.end(); it){ // 姓名不变直接输出 cout it-name ; // 年龄自动加 1 cout it-year 1 ; // 成绩提升 20%但要注意上限 600 if(it-score * 1.2 600) cout 600 endl; else cout it-score * 1.2 endl; }⚠️ 细节决定成败这里有个小坑题目说了成绩不能超过 600。虽然乘以 1.2 很简单但我们必须加上一个if判断来进行“截断”。编程不仅要算得对还要符合现实世界的规则 关卡三谁是“旗鼓相当”的对手最后一题稍微有点难度P5741【深基 7.例 10】旗鼓相当的对手 - 加强版。 题目大意如果有两个学生他们的语文、数学、英语分差都不超过 5 分且总分差不超过 10 分那他们就是“旗鼓相当的对手”。请找出所有这样的组合。 核心思路双重循环暴力匹配这道题的数据范围N1000 我们可以放心地使用双重循环来两两比较。// 判断是否为对手的函数 bool isRival(const student s1, const student s2){ if(abs(s1.a - s2.a) 5 abs(s1.b - s2.b) 5 abs(s1.c - s2.c) 5 abs(s1.score - s2.score) 10) returntrue; else returnfalse; } int main(){ // ... 输入部分省略 ... // 双重循环查找 for(int i 0; i s.size(); i){ for(int j i 1; j s.size(); j){ // 只比较后面的避免重复输出 (A,B) 和 (B,A) if(isRival(s[i], s[j])){ cout s[i].name s[j].name endl; } } } return0; } 为什么这样写封装判断逻辑我把判断条件写在了isRival函数里主函数看起来就非常清爽。去重技巧内层循环从j i 1开始。这意味着我们只拿第 个人和他后面的人比。这样既不会自己和自己比也不会出现“A和B是对手B和A也是对手”的重复情况。 总结一下今天我们通过三道题掌握了结构体的三大用法P5740利用结构体进行整体排序记得stable_sort。P5744利用结构体进行批量数据处理遍历修改。P5741利用结构体进行对象间的关系匹配双重循环。如果你觉得这篇文章对你有帮助欢迎点赞、在看、转发三连支持一下你的鼓励是我更新的最大动力❤️
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2641264.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!