当前位置: 首页 > news >正文

信息学奥赛刷题笔记:OpenJudge NOI 1.10 06题,我用两种思路搞定整数奇偶排序

信息学奥赛刷题笔记:OpenJudge NOI 1.10 06题,我用两种思路搞定整数奇偶排序

在信息学竞赛的刷题过程中,遇到排序类题目时,很多初学者往往只满足于实现基本功能,而忽略了多种解法的探索。今天我们就以OpenJudge NOI 1.10 06题"整数奇偶排序"为例,深入剖析两种截然不同的解题思路,帮助你在算法竞赛中培养灵活的思维方式。

1. 题目分析与基础解法

1.1 题目要求解析

题目要求对10个整数进行排序,排序规则为:

  • 所有奇数排在偶数前面
  • 奇数之间按从大到小排序
  • 偶数之间按从小到大排序

这种复合排序规则在实际编程竞赛中很常见,它考察的是对排序算法的灵活运用能力。我们先来看最直观的解法——分组排序法。

1.2 分组排序法实现

分组排序法的核心思想是将奇数和偶数分离到两个不同的数组中,分别排序后再合并输出。这种方法思路清晰,适合初学者理解和实现。

#include <bits/stdc++.h> using namespace std; bool cmpUp(int a, int b) { return a < b; } // 升序比较函数 bool cmpDown(int a, int b) { return a > b; } // 降序比较函数 int main() { int num, odd[15], even[15], oi = 0, ei = 0; for(int i = 0; i < 10; ++i) { cin >> num; if(num % 2 == 0) even[ei++] = num; // 存储偶数 else odd[oi++] = num; // 存储奇数 } sort(odd, odd + oi, cmpDown); // 奇数降序排序 sort(even, even + ei, cmpUp); // 偶数升序排序 for(int i = 0; i < oi; ++i) cout << odd[i] << ' '; for(int i = 0; i < ei; ++i) cout << even[i] << ' '; return 0; }

这种方法有几个关键点需要注意:

  1. 数组下标从0开始更符合C++常规用法
  2. 使用STL的sort函数可以大幅简化排序实现
  3. 需要正确定义升序和降序的比较函数

提示:在实际竞赛中,使用标准库函数通常比手写排序更可靠且不易出错,除非题目明确要求实现特定排序算法。

2. 进阶解法:自定义比较函数

2.1 单一排序的优雅实现

分组排序虽然直观,但需要额外的存储空间和两次排序操作。更优雅的解法是定义一个复合比较函数,通过一次排序完成所有要求。

#include <bits/stdc++.h> using namespace std; bool cmp(int a, int b) { if(a%2 != b%2) // 奇偶性不同 return a%2 > b%2; // 奇数排在前面 else if(a%2) // 都是奇数 return a > b; // 降序排列 else // 都是偶数 return a < b; // 升序排列 } int main() { int nums[10]; for(int i = 0; i < 10; ++i) cin >> nums[i]; sort(nums, nums + 10, cmp); for(int i = 0; i < 10; ++i) cout << nums[i] << ' '; return 0; }

2.2 比较函数设计原理

这个自定义比较函数的设计体现了排序问题的核心逻辑:

  1. 奇偶优先:通过比较a%2 > b%2确保奇数始终排在偶数前面
  2. 奇数降序:当两个数都是奇数时,返回a > b实现降序
  3. 偶数升序:当两个数都是偶数时,返回a < b实现升序

这种方法的优势在于:

  • 只需要一次排序操作
  • 不需要额外的存储空间
  • 代码更加简洁优雅
  • 更容易扩展到更复杂的排序规则

3. 两种解法的性能对比

虽然题目数据量很小(仅10个数),但了解不同解法的性能特点对算法学习很有帮助。

对比维度分组排序法自定义比较函数法
时间复杂度O(n log n) × 2O(n log n)
空间复杂度O(n)O(1)
代码复杂度中等较高
扩展性一般优秀
适用场景规则简单的复合排序规则复杂的复合排序

从表中可以看出,自定义比较函数法在大多数方面都优于分组排序法,特别是当排序规则变得更加复杂时。

4. 常见错误与调试技巧

4.1 新手易犯的错误

  1. 数组下标混淆:有些教材使用1-based索引,而C++默认是0-based
  2. 比较函数逻辑错误:特别是复合条件的优先级问题
  3. 奇偶判断不严谨:负数取模在不同语言中结果可能不同
  4. 输出格式不符:末尾多余空格或缺少空格

4.2 调试建议

  • 使用小规模测试数据验证边界条件
  • 打印中间结果检查排序过程
  • 单独测试比较函数的正确性
  • 使用assert验证不变量
// 测试比较函数的示例 void test_cmp() { assert(cmp(3, 2) == true); // 奇>偶 assert(cmp(2, 3) == false); // 偶<奇 assert(cmp(5, 3) == true); // 奇>奇 assert(cmp(2, 4) == true); // 偶<偶 cout << "All test cases passed!" << endl; }

5. 算法扩展与应用

5.1 更复杂的排序规则

掌握了自定义比较函数的方法后,可以解决更复杂的排序问题,例如:

  • 按照数字各位数之和排序
  • 按照字符串的特殊规则排序
  • 多关键字复合排序

5.2 其他排序算法实现

虽然STL的sort函数足够强大,但了解其他排序算法的实现也有助于深入理解排序原理。

使用快速排序实现:

void quickSort(int arr[], int left, int right, bool (*cmp)(int, int)) { if(left >= right) return; int pivot = arr[(left+right)/2]; int i = left, j = right; while(i <= j) { while(cmp(arr[i], pivot)) i++; while(cmp(pivot, arr[j])) j--; if(i <= j) swap(arr[i++], arr[j--]); } quickSort(arr, left, j, cmp); quickSort(arr, i, right, cmp); }

5.3 实际应用场景

这类复合排序在实际开发中很常见,例如:

  • 电商商品排序(销量+评分+价格)
  • 学生成绩排名(总分+单科成绩)
  • 任务调度优先级(紧急程度+截止时间)
http://www.jsqmd.com/news/988349/

相关文章:

  • 手把手教你搞定VL822 HUB的复位时序:用PD芯片GPIO复位,还是用HUB自身复位脚?
  • 实战指南:用Verilog二维数组在FPGA上实现一个简单的图像卷积核(附SystemVerilog简化写法)
  • 别再手动调图了!用ggh4x包的facetted_pos_scales函数,5分钟搞定ggplot2分面坐标轴难题
  • 从IP核到原语:手把手教你读懂Xilinx MMCME2_ADV时钟配置源码(附参数对照表)
  • 2026年广告创意公司/医药广告创意代理TOP5榜单:品牌策略与合规传播的破局之道 - 品牌发掘
  • WiFi定频测试避坑指南:从QRCT连接失败到射频线缆选择,这些细节决定成败
  • 避坑指南:华为AC旁挂组网,Option 43配错导致AP不上线?手把手教你三层发现AC的正确姿势
  • 告别卡顿!从RRC重配置流程看手游/直播为何突然流畅——5G QoS的幕后功臣DRB建立详解
  • 生产级机器学习系统:从模型部署到持续治理的四大支柱
  • Altium Designer 19 自定义库管理实战:解决‘画了找不到’和工具栏消失问题
  • 2026年6月最新版苏州第三方CMACNAS甲醛检测治理机构口碑名单:万清CMA检测中心等5家公司深度测评万清CMA检测中心TOP1推荐 - 一休咨询
  • CloudCompare点云高程归一化保姆级教程:从CSF到泊松重建,四种方法实测对比与避坑指南
  • 数据岗位技能分析实战:从JD爬取到能力图谱建模
  • Python 爬虫项目 Cookie 池搭建与会话隔离实战
  • 手机拍Vlog,用剪映导出选‘推荐码率’还是‘自定义’?实测告诉你差别有多大
  • MongoDB用户权限管理入门:除了root,你更应该知道如何创建只读和应用账号
  • 从一行RTL代码到最终芯片:手把手拆解Synopsys工具链在数字IC设计中的实战联动
  • RimWorld Mod开发避坑指南:这50+个Def类型,新手千万别自己从头写
  • MuleSoft+LangChain企业级AI编排实战:安全可控的LLM集成方案
  • 从‘Hello World’到打印金字塔:我的C语言入门项目实战复盘(附VS2022调试技巧)
  • 多维聚合实战:ROLLUP、CUBE与GROUPING SETS原理与优化
  • mysql应用层分表(Application-Level Sharding)知识笔记
  • 2026年6月市场专业的悬臂焊接机器人供应商哪家专业,埋弧焊机器人/电力焊接机器人,悬臂焊接机器人厂家找哪家 - 品牌推荐师
  • MySQL字段里存了‘a,b,c’?教你用SUBSTRING_INDEX和REPLACE函数搞定拆分与精准查询
  • 五条超级智能实现路径的技术可行性分析框架
  • 多维聚合中的数据操纵:从OLAP立方体到CEO驾驶舱的四层解剖
  • 从OpenJudge一道题出发,聊聊C++里处理字符串输入的那些“坑”与技巧
  • 不止是列表:用RimWorld的Def系统设计你的第一个原创事件(IncidentDef实战)
  • 告别手动造数据:用SystemVerilog的$fscanf和$fwrite自动化你的测试平台
  • 告别AP直连:用华为AC+交换机搭建可扩展的无线办公网(隧道转发详解)