算法竞赛入门经典(第2版).刘汝佳(带书签文字版).pdf
本书是一本算法竞赛的入门与提高教材,把C/C++语言、算法和解题有机地结合在一起,淡化理论,注重学习方法和实践技巧。全书内容分为12章,包括程序设计入门、循环结构程序设计、数组和字符串、函数和递归、C++与STL入门、数据结构基础、暴力求解法、高效算法设计、动态规划初步、数学概念与方法、图论模型与算法、高级专题等内容,覆盖了算法竞赛入门和提高所需的主要知识点,并含有大量例题和习题。书中的代码规范、简洁、易懂,不仅能帮助读者理解算法原理,还能教会读者很多实用的编程技巧;书中包含的各种开发、测试和调试技巧也是传统的语言、算法类书籍中难以见到的。本书可作为全国青少年信息学奥林匹克联赛(NOIP)复赛教材、全国青少年信息学奥林匹克竞赛(NOI)和ACM国际大学生程序设 计竞赛(ACM/ICPC)的训练资料,也可作为IT工程师与科研人员的参考用书。 第1部分 语言篇 第1章 程序设计入门 1 1.1 算术表达式 1 1.2 变量及其输入 3 1.3 顺序结构程序设计 6 1.4 分支结构程序设计 9 1.5 小结与习题 13 1.5.1 数据类型实验 13 1.5.2 scanf输入格式实验 13 1.5.3 printf语句输出实验 13 1.5.4 测测你的实践能力 14 1.5.5 小结 14 1.5.6 上机练习 15 第2章 循环结构程序设计 16 2.1 for循环 16 2.2 循环结构程序设计 19 2.3 文件操作 23 2.4 小结与习题 27 2.4.1 输出技巧 28 2.4.2 浮点数陷阱 28 2.4.3 64位整数 28 2.4.4 C++中的输入输出 29 2.4.5 小结 30 2.4.6 上机练习 31 第3章 数组和字符串 33 3.1 数组 33 3.2 字符数组 37 3.3 最长回文子串 41 3.4 小结与习题 45 3.4.1 必要的存储量 45 3.4.2 用ASCII编码表示字符 45 3.4.3 补码表示法 46 3.4.4 重新实现库函数 47 3.4.5 字符串处理的常见问题 47 3.4.6 关于输入输出 47 3.4.7 I/O的效率 47 3.4.8 小结 49 3.4.9 上机练习 50 第4章 函数和递归 51 4.1 数学函数 51 4.1.1 简单函数的编写 51 4.1.2 使用结构体的函数 52 4.1.3 应用举例 53 4.2 地址和指针 56 4.2.1 变量交换 56 4.2.2 调用栈 57 4.2.3 用指针实现变量交换 59 4.2.4 初学者易犯的错误 61 4.3 递归 62 4.3.1 递归定义 62 4.3.2 递归函数 63 4.3.3 C语言对递归的支持 64 4.3.4 段错误与栈溢出 66 4.4 本章小结 67 4.4.1 小问题集锦 67 4.4.2 小结 68 第2部分 算法篇 第5章 基础题目选解 69 5.1 字符串 69 5.1.1 WERTYU 69 5.1.2 TeX括号 70 5.1.3 周期串 71 5.2 高精度运算 71 5.2.1 小学生算术 72 5.2.2 阶乘的精确值 72 5.2.3 高精度运算类bign 73 5.2.4 重载bign的常用运算符 75 5.3 排序与检索 77 5.3.1 6174问题 77 5.3.2 字母重排 78 5.4 数学基础 81 5.4.1 Cantor的数表 81 5.4.2 因子和阶乘 82 5.4.3 果园里的树 84 5.4.4 多少块土地 86 5.5 训练参考 86 5.5.1 黑盒测试 86 5.5.2 在线评测系统 87 5.5.3 推荐题目 88 第6章 数据结构基础 89 6.1 栈和队列 89 6.1.1 卡片游戏 89 6.1.2 铁轨 91 6.2 链表 93 6.2.1 初步分析 93 6.2.2 链式结构 95 6.2.3 对比测试 96 6.2.4 随机数发生器 98 6.3 二叉树 99 6.3.1 小球下落 99 6.3.2 层次遍历 101 6.3.3 二叉树重建 105 6.4 图 106 6.4.1 黑白图像 107 6.4.2 走迷宫 108 6.4.3 拓扑排序 110 6.4.4 欧拉回路 111 6.5 训练参考 112 第7章 暴力求解法 114 7.1 简单枚举 114 7.1.1 除法 114 7.1.2 最大乘积 115 7.1.3 分数拆分 115 7.1.4 双基回文数 116 7.2 枚举排列 116 7.2.1 生成1~n的排列 116 7.2.2 生成可重集的排列 118 7.2.3 解答树 118 7.2.4 下一个排列 119 7.3 子集生成 120 7.3.1 增量构造法 120 7.3.2 位向量法 121 7.3.3 二进制法 122 7.4 回溯法 123 7.4.1 八皇后问题 123 7.4.2 素数环 126 7.4.3 困难的串 127 7.4.4 带宽 128 7.5 隐式图搜索 129 7.5.1 隐式树的遍历 129 7.5.2 一般隐式图的遍历 130 7.5.3 八数码问题 131 7.5.4 结点查找表 133 7.6 训练参考 136 第8章 高效算法设计 138 8.1 算法分析初步 138 8.1.1 渐进时间复杂度 138 8.1.2 上界分析 140 8.1.3 分治法 140 8.1.4 正确对待算法分析结果 142 8.2 再谈排序与检索 143 8.2.1 归并排序 143 8.2.2 快速排序 145 8.2.3 二分查找 145 8.3 递归与分治 148 8.3.1 棋盘覆盖问题 148 8.3.2 循环日程表问题 149 8.3.3 巨人与鬼 149 8.3.4 非线性方程求根 150 8.3.5 最大值最小化 151 8.4 贪心法 151 8.4.1 最优装载问题 151 8.4.2 部分背包问题 152 8.4.3 乘船问题 152 8.4.4 选择不相交区间 152 8.4.5 区间选点问题 153 8.4.6 区间覆盖问题 154 8.4.7 Huffman编码 154 8.5 训练参考 156 第3部分 竞赛篇 第9章 动态规划初步 158 9.1 数字三角形 158 9.1.1 问题描述与状态定义 158 9.1.2 记忆化搜索与递推 159 9.2 DAG上的动态规划 161 9.2.1 DAG模型 161 9.2.2 最长路及其字典序 162 9.2.3 固定终点的最长路和最短路 163 9.3 0-1背包问题 167 9.3.1 多阶段决策问题 167 9.3.2 规划方向 168 9.3.3 滚动数组 169 9.4 递归结构中的动态规划 170 9.4.1 表达式上的动态规划 170 9.4.2 凸多边形上的动态规划 171 9.4.3 树上的动态规划 171 9.5 集合上的动态规划 172 9.5.1 状态及其转移 173 9.5.2 隐含的阶段 173 9.6 训练参考 174 第10章 数学概念与方法 176 10.1 数论初步 176 10.1.1 除法表达式 176 10.1.2 无平方因子的数 178 10.1.3 直线上的点 179 10.1.4 同余与模算术 180 10.2 排列与组合 182 10.2.1 杨辉三角与二项式定理 182 10.2.2 数论中的计数问题 184 10.2.3 编码与解码 186 10.2.4 离散概率初步 187 10.3 递推关系 188 10.3.1 汉诺塔 188 10.3.2 Fibonacci数列 189 10.3.3 Catalan数 191 10.3.4 危险的组合 192 10.3.5 统计n-k特殊集的数目 193 10.4 训练参考 194 第11章 图论模型与算法 196 11.1 再谈树 196 11.1.1 无根树转有根树 196 11.1.2 表达式树 197 11.1.3 最小生成树 199 11.1.4 并查集 200 11.2 最短路问题 201 11.2.1 Dijkstra算法 202 11.2.2 稀疏图的邻接表 203 11.2.3 使用优先队列的Dijkstra算法 204 11.2.4 Bellman-Ford算法 205 11.2.5 Floyd算法 206 11.3 网络流初步 207 11.3.1 最大流问题 207 11.3.2 增广路算法 208 11.3.3 最小割最大流定理 210 11.3.4 最小费用最大流问题 211 11.4 进一步学习的参考 212 11.4.1 编程语言 213 11.4.2 数据结构 213 11.4.3 算法设计 213 11.4.4 数学 214 11.4.5 参赛指南 214 11.5 训练参考 215 附录A 开发环境与方法 216 A.1 命令行 216 A.1.1 文件系统 216 A.1.2 进程 217 A.1.3 程序的执行 217 A.1.4 重定向和管道 218 A.1.5 常见命令 218 A.2 操作系统脚本编程入门 219 A.2.1 Windows下的批处理 219 A.2.2 Linux下的Bash脚本 220 A.2.3 再谈随机数 221 A.3 编译器和调试器 221 A.3.1 gcc的安装和测试 221 A.3.2 常见编译选项 222 A.3.3 gdb简介 223 A.3.4 gdb的高级功能 224 A.4 浅谈IDE 225 计竞赛(ACM/ICPC)的训练资料,也可作为IT工程师与科研人员的参考用书。 第1部分 语言篇 第1章 程序设计入门 1 1.1 算术表达式 1 1.2 变量及其输入 3 1.3 顺序结构程序设计 6 1.4 分支结构程序设计 9 1.5 小结与习题 13 1.5.1 数据类型实验 13 1.5.2 scanf输入格式实验 13 1.5.3 printf语句输出实验 13 1.5.4 测测你的实践能力 14 1.5.5 小结 14 1.5.6 上机练习 15 第2章 循环结构程序设计 16 2.1 for循环 16 2.2 循环结构程序设计 19 2.3 文件操作 23 2.4 小结与习题 27 2.4.1 输出技巧 28 2.4.2 浮点数陷阱 28 2.4.3 64位整数 28 2.4.4 C++中的输入输出 29 2.4.5 小结 30 2.4.6 上机练习 31 第3章 数组和字符串 33 3.1 数组 33 3.2 字符数组 37 3.3 最长回文子串 41 3.4 小结与习题 45 3.4.1 必要的存储量 45 3.4.2 用ASCII编码表示字符 45 3.4.3 补码表示法 46 3.4.4 重新实现库函数 47 3.4.5 字符串处理的常见问题 47 3.4.6 关于输入输出 47 3.4.7 I/O的效率 47 3.4.8 小结 49 3.4.9 上机练习 50 第4章 函数和递归 51 4.1 数学函数 51 4.1.1 简单函数的编写 51 4.1.2 使用结构体的函数 52 4.1.3 应用举例 53 4.2 地址和指针 56 4.2.1 变量交换 56 4.2.2 调用栈 57 4.2.3 用指针实现变量交换 59 4.2.4 初学者易犯的错误 61 4.3 递归 62 4.3.1 递归定义 62 4.3.2 递归函数 63 4.3.3 C语言对递归的支持 64 4.3.4 段错误与栈溢出 66 4.4 本章小结 67 4.4.1 小问题集锦 67 4.4.2 小结 68 第2部分 算法篇 第5章 基础题目选解 69 5.1 字符串 69 5.1.1 WERTYU 69 5.1.2 TeX括号 70 5.1.3 周期串 71 5.2 高精度运算 71 5.2.1 小学生算术 72 5.2.2 阶乘的精确值 72 5.2.3 高精度运算类bign 73 5.2.4 重载bign的常用运算符 75 5.3 排序与检索 77 5.3.1 6174问题 77 5.3.2 字母重排 78 5.4 数学基础 81 5.4.1 Cantor的数表 81 5.4.2 因子和阶乘 82 5.4.3 果园里的树 84 5.4.4 多少块土地 86 5.5 训练参考 86 5.5.1 黑盒测试 86 5.5.2 在线评测系统 87 5.5.3 推荐题目 88 第6章 数据结构基础 89 6.1 栈和队列 89 6.1.1 卡片游戏 89 6.1.2 铁轨 91 6.2 链表 93 6.2.1 初步分析 93 6.2.2 链式结构 95 6.2.3 对比测试 96 6.2.4 随机数发生器 98 6.3 二叉树 99 6.3.1 小球下落 99 6.3.2 层次遍历 101 6.3.3 二叉树重建 105 6.4 图 106 6.4.1 黑白图像 107 6.4.2 走迷宫 108 6.4.3 拓扑排序 110 6.4.4 欧拉回路 111 6.5 训练参考 112 第7章 暴力求解法 114 7.1 简单枚举 114 7.1.1 除法 114 7.1.2 最大乘积 115 7.1.3 分数拆分 115 7.1.4 双基回文数 116 7.2 枚举排列 116 7.2.1 生成1~n的排列 116 7.2.2 生成可重集的排列 118 7.2.3 解答树 118 7.2.4 下一个排列 119 7.3 子集生成 120 7.3.1 增量构造法 120 7.3.2 位向量法 121 7.3.3 二进制法 122 7.4 回溯法 123 7.4.1 八皇后问题 123 7.4.2 素数环 126 7.4.3 困难的串 127 7.4.4 带宽 128 7.5 隐式图搜索 129 7.5.1 隐式树的遍历 129 7.5.2 一般隐式图的遍历 130 7.5.3 八数码问题 131 7.5.4 结点查找表 133 7.6 训练参考 136 第8章 高效算法设计 138 8.1 算法分析初步 138 8.1.1 渐进时间复杂度 138 8.1.2 上界分析 140 8.1.3 分治法 140 8.1.4 正确对待算法分析结果 142 8.2 再谈排序与检索 143 8.2.1 归并排序 143 8.2.2 快速排序 145 8.2.3 二分查找 145 8.3 递归与分治 148 8.3.1 棋盘覆盖问题 148 8.3.2 循环日程表问题 149 8.3.3 巨人与鬼 149 8.3.4 非线性方程求根 150 8.3.5 最大值最小化 151 8.4 贪心法 151 8.4.1 最优装载问题 151 8.4.2 部分背包问题 152 8.4.3 乘船问题 152 8.4.4 选择不相交区间 152 8.4.5 区间选点问题 153 8.4.6 区间覆盖问题 154 8.4.7 Huffman编码 154 8.5 训练参考 156 第3部分 竞赛篇 第9章 动态规划初步 158 9.1 数字三角形 158 9.1.1 问题描述与状态定义 158 9.1.2 记忆化搜索与递推 159 9.2 DAG上的动态规划 161 9.2.1 DAG模型 161 9.2.2 最长路及其字典序 162 9.2.3 固定终点的最长路和最短路 163 9.3 0-1背包问题 167 9.3.1 多阶段决策问题 167 9.3.2 规划方向 168 9.3.3 滚动数组 169 9.4 递归结构中的动态规划 170 9.4.1 表达式上的动态规划 170 9.4.2 凸多边形上的动态规划 171 9.4.3 树上的动态规划 171 9.5 集合上的动态规划 172 9.5.1 状态及其转移 173 9.5.2 隐含的阶段 173 9.6 训练参考 174 第10章 数学概念与方法 176 10.1 数论初步 176 10.1.1 除法表达式 176 10.1.2 无平方因子的数 178 10.1.3 直线上的点 179 10.1.4 同余与模算术 180 10.2 排列与组合 182 10.2.1 杨辉三角与二项式定理 182 10.2.2 数论中的计数问题 184 10.2.3 编码与解码 186 10.2.4 离散概率初步 187 10.3 递推关系 188 10.3.1 汉诺塔 188 10.3.2 Fibonacci数列 189 10.3.3 Catalan数 191 10.3.4 危险的组合 192 10.3.5 统计n-k特殊集的数目 193 10.4 训练参考 194 第11章 图论模型与算法 196 11.1 再谈树 196 11.1.1 无根树转有根树 196 11.1.2 表达式树 197 11.1.3 最小生成树 199 11.1.4 并查集 200 11.2 最短路问题 201 11.2.1 Dijkstra算法 202 11.2.2 稀疏图的邻接表 203 11.2.3 使用优先队列的Dijkstra算法 204 11.2.4 Bellman-Ford算法 205 11.2.5 Floyd算法 206 11.3 网络流初步 207 11.3.1 最大流问题 207 11.3.2 增广路算法 208 11.3.3 最小割最大流定理 210 11.3.4 最小费用最大流问题 211 11.4 进一步学习的参考 212 11.4.1 编程语言 213 11.4.2 数据结构 213 11.4.3 算法设计 213 11.4.4 数学 214 11.4.5 参赛指南 214 11.5 训练参考 215 附录A 开发环境与方法 216 A.1 命令行 216 A.1.1 文件系统 216 A.1.2 进程 217 A.1.3 程序的执行 217 A.1.4 重定向和管道 218 A.1.5 常见命令 218 A.2 操作系统脚本编程入门 219 A.2.1 Windows下的批处理 219 A.2.2 Linux下的Bash脚本 220 A.2.3 再谈随机数 221 A.3 编译器和调试器 221 A.3.1 gcc的安装和测试 221 A.3.2 常见编译选项 222 A.3.3 gdb简介 223 A.3.4 gdb的高级功能 224 A.4 浅谈IDE 225
用户评论