ACM基础算法入门教程
acm程序设计竞赛基础教程
acm程序设计竞赛基础教程
ACM程序设计竞赛基础教程是一本专门针对ACM程序设计竞赛的教程,该书由中国大学MOOC(慕课)在线教育平台和北京大学计算机科学与技术系合作,主要面向程序设计竞赛爱好者和准备参加竞赛的学生。
本教程共分为10个章节,从基础的算法和数据结构开始讲解,到高级的算法和数据结构,并涵盖了常见的编程语言和各种经典算法的实现和应用。
每个章节都有一些简单的例子和练习题,旨在帮助学生巩固所学的知识和提高编程能力。
本教程的作者是来自北京大学计算机科学与技术系的教授和研究生,他们有丰富的ACM竞赛经验和创新思维,对于如何有效地学习和练习编程有着深入的理解和实践。
同时,本教材也收录了一些国际著名的ACM竞赛题目和优秀的代码答案,以便学生更好地了解和掌握这个领域的最新进展和应用。
总之,ACM程序设计竞赛基础教程是一本集理论和实践于一体的学习资料,对于想要学习和了解ACM竞赛的人来说是一本必备的参考书。
ACM基础算法入门讲述
会场安排问题
先对n个区间按照bi从小到大的顺序排序,如果 bi相同,则ai按照从大到小的顺序排序。然后从前往后 扫描每个区间,找出所有的符合条件的区间。
注意:排序后第一个区间一定会选,因为它的bi 最小, 它不影响后面区间的选取,而且如果不选此区间,最 终 求出的区间数目会变少。
区间选点问题
0 1 0 0 1
解题过程
本题是简单的搜索问题,采用深度优先 遍历可以解决,根据题目要求,假设从 任意一点值为'1'的出发,将这点的坐标 上下左右全部用'0'替换,1次DFS后与初 始动这个'1'连接的'1'全部被替换成'0', 因此,直到图中不再存在'1'为至,总共 进行的DFS的次数就是最后的结果咯!那 么,根据题目要求,有4个方向,时间复 杂度为O(4*n*m)。
如:1 9 10 5 11 2 13的最长单调递增子 序列是1 9 10 11 13,长度为5。
解题思路
定义状态 dp【i】以i为结束节点最长单调子序列长度 阶段 每一个点选择过程即阶段 转移方程: Dp【i】= max(dp【1~(i-1)】) + 1 想想有没有更好的方法???
dp总结
例题:
水池数目 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池, 假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在, 你的任务来了,请用计算机算出该地图中共有几个水池。 输入m行每行输入n个数,表示此处有水还是没水 (1表示此处是水池,0表示此处是地面) 0<m<100 0<n<100 输入: 34 1000 0011 1110 输出: 2 输入: 55 1111 0010 0000 1110 0011 输出: 3
ACM入门
输入输出
• 读一个非空白字符, • 方法一:
– char str[2]; scanf(“%1s”, str); – // %1s扫描前导空白,并且只读一个字符 – char c = str[0];
• 方法二:
– 强制扫描空白 – 在%前面加上一个空格表示“强制扫描前导空白” – scanf(“ %c”, &ch); – 前面那个读人物信息的完整scanf语句:
17
Related Resource
• TopCoder :
– /tc
• 一个月4次左右,有rating • 分两个版(Div I, Div II) • 参加人数众多 • 每次比赛后有详细的解题报告、代码 • 比赛结束后有Practice Room可以继续做 • 可以查看每一个人的代码 • Forum很热闹,乐于助人 • 有$
– 1支队伍1台机器(提供打印服务)
– 上机编程解决问题(可以携带诸如书、手册、 程序清单等
参考资料;不能携带任何可用计算机处理的软件或数据、不 能携带任何类型的通讯工具)
– 实时测试,动态排名
• 试题
– 6-10题
– 全英文(可以带字典) • 时间:持续5个小时;
8
• 支持语言:c/c++, java, pascal
29
Input • The input will consist of a series of pairs of integers a and b, separated by a space, one pair of integers per line. Output • For each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input. Sample Input • 15 • 10 20 Sample Output • 6 30 • 30
ACMer需要掌握的算法讲解
ACM主要算法介绍初期篇一、基本算法(1)枚举(poj1753, poj2965)(2)贪心(poj1328, poj2109, poj2586)(3)递归和分治法(4)递推(5)构造法(poj3295)(6)模拟法(poj1068, poj2632, poj1573, poj2993, poj2996)二、图算法(1)图的深度优先遍历和广度优先遍历(2)最短路径算法(dijkstra, bellman-ford, floyd, heap+dijkstra)(poj1860, poj3259, poj1062, poj2253, poj1125, poj2240)(3)最小生成树算法(prim, kruskal)(poj1789, poj2485, poj1258, poj3026)(4)拓扑排序(poj1094)(5)二分图的最大匹配(匈牙利算法)(poj3041, poj3020)(6)最大流的增广路算法(KM算法)(poj1459, poj3436)三、数据结构(1)串(poj1035, poj3080, poj1936)(2)排序(快排、归并排(与逆序数有关)、堆排)(poj2388, poj2299)(3)简单并查集的应用(4)哈希表和二分查找等高效查找法(数的Hash, 串的Hash)(poj3349, poj3274, POJ2151, poj1840, poj2002, poj2503)(5)哈夫曼树(poj3253)(6)堆(7)trie树(静态建树、动态建树)(poj2513)四、简单搜索(1)深度优先搜索(poj2488, poj3083, poj3009, poj1321, poj2251)(2)广度优先搜索(poj3278, poj1426, poj3126, poj3087, poj3414)(3)简单搜索技巧和剪枝(poj2531, poj1416, poj2676, 1129)五、动态规划(1)背包问题(poj1837, poj1276)(2)型如下表的简单DP(可参考lrj的书page149):1.E[j]=opt{D+w(i,j)} (poj3267, poj1836, poj1260, poj2533)2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)(poj3176, poj1080, poj1159)3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]} (最优二分检索树问题)六、数学(1)组合数学1.加法原理和乘法原理2.排列组合3.递推关系(poj3252, poj1850, poj1019, poj1942)(2)数论1.素数与整除问题2.进制位3.同余模运算(poj2635, poj3292, poj1845, poj2115)(3)计算方法1.二分法求解单调函数相关知识(poj3273, poj3258, poj1905, poj3122)七、计算几何学(1)几何公式(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等)(poj2031, poj1039)(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)(poj1408, poj1584)(4)凸包(poj2187, poj1113)中级篇一、基本算法(1)C++的标准模版库的应用(poj3096, poj3007)(2)较为复杂的模拟题的训练(poj3393, poj1472, poj3371, poj1027,poj2706)二、图算法(1)差分约束系统的建立和求解(poj1201, poj2983)(2)最小费用最大流(poj2516, poj2195)(3)双连通分量(poj2942)(4)强连通分支及其缩点(poj2186)(5)图的割边和割点(poj3352)(6)最小割模型、网络流规约(poj3308)三、数据结构(1)线段树(poj2528, poj2828, poj2777, poj2886, poj2750)(2)静态二叉检索树(poj2482, poj2352)(3)树状树组(poj1195, poj3321)(4)RMQ(poj3264, poj3368)(5)并查集的高级应用(poj1703, 2492)(6)KMP算法(poj1961, poj2406)四、搜索(1)最优化剪枝和可行性剪枝(2)搜索的技巧和优化(poj3411, poj1724)(3)记忆化搜索(poj3373, poj1691)五、动态规划(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)(poj1191, poj1054, poj3280, poj2029, poj2948, poj1925, poj3034)(2)记录状态的动态规划(poj3254, poj2411, poj1185)(3)树型动态规划(poj2057, poj1947, poj2486, poj3140)六、数学(1)组合数学1.容斥原理2.抽屉原理3.置换群与Polya定理(poj1286, poj2409, poj3270, poj1026)4.递推关系和母函数(2)数学1.高斯消元法(poj2947, poj1487, poj2065, poj1166, poj1222)2.概率问题(poj3071, poj3440)3.GCD、扩展的欧几里德(中国剩余定理)(poj3101)(3)计算方法1.0/1分数规划(poj2976)2.三分法求解单峰(单谷)的极值3.矩阵法(poj3150, poj3422, poj3070)4.迭代逼近(poj3301)(4)随机化算法(poj3318, poj2454)(5)杂题(poj1870, poj3296, poj3286, poj1095)七、计算几何学(1)坐标离散化(2)扫描线算法(例如求矩形的面积和周长,并常和线段树或堆一起使用)(poj1765, poj1177, poj1151, poj3277, poj2280, poj3004)(3)多边形的内核(半平面交)(poj3130, poj3335)(4)几何工具的综合应用(poj1819, poj1066, poj2043, poj3227, poj2165, poj3429)高级篇一、基本算法要求(1)代码快速写成,精简但不失风格(poj2525, poj1684, poj1421,poj1048, poj2050, poj3306)(2)保证正确性和高效性(poj3434)二、图算法(1)度限制最小生成树和第K最短路(poj1639)(2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)(poj3155, poj2112, poj1966, poj3281, poj1087, poj2289, poj3216, poj2446)(3)最优比率生成树(poj2728)(4)最小树形图(poj3164)(5)次小生成树(6)无向图、有向图的最小环三、数据结构(1)trie图的建立和应用(poj2778)(2)LCA和RMQ问题(LCA(最近公共祖先问题),有离线算法(并查集+dfs)和在线算法(RMQ+dfs))(poj1330)(3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的目的)(poj2823)(4)左偏树(可合并堆)(5)后缀树(非常有用的数据结构,也是赛区考题的热点)(poj3415,poj3294)四、搜索(1)较麻烦的搜索题目训练(poj1069, poj3322, poj1475, poj1924,poj2049, poj3426)(2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法(poj1768, poj1184, poj1872, poj1324, poj2046, poj1482)(3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法(poj3131, poj2870, poj2286)五、动态规划(1)需要用数据结构优化的动态规划(poj2754, poj3378, poj3017)(2)四边形不等式理论(3)较难的状态DP(poj3133)六、数学(1)组合数学1.MoBius反演(poj2888, poj2154)2.偏序关系理论(2)博奕论1.极大极小过程(poj3317, poj1085)2.Nim问题七、计算几何学(1)半平面求交(poj3384, poj2540)(2)可视图的建立(poj2966)(3)点集最小圆覆盖(4)对踵点(poj2079)八、综合题(poj3109, poj1478, poj1462, poj2729, poj2048, poj3336, poj3315, poj2148, poj1263)附录:POJ是“北京大学程序在线评测系统”(Peking University Online Judge)的缩写,是个提供编程题目的网站,兼容Pascal、C、C++、Java、Fortran等多种语言。
ACM程序设计算法讲解
目录1.河内之塔 .............................................................................................................. 错误!未定义书签。
Gossip: 费式数列 ................................................................................................. 错误!未定义书签。
3.巴斯卡三角形 .................................................. 错误!未定义书签。
Gossip: 三色棋.................................................. 错误!未定义书签。
Gossip: 老鼠走迷官(一)........................................ 错误!未定义书签。
Gossip: 老鼠走迷官(二)........................................ 错误!未定义书签。
Gossip: 骑士走棋盘.............................................. 错误!未定义书签。
Gossip: 八皇后.................................................. 错误!未定义书签。
Gossip: 八枚银币................................................ 错误!未定义书签。
Gossip: 生命游戏................................................ 错误!未定义书签。
Gossip: 字串核对................................................ 错误!未定义书签。
ACM基础算法入门教程
ACM基础算法入门教程ACM(ACM International Collegiate Programming Contest)是国际大学生程序设计竞赛的缩写,被认为是计算机领域最有权威和最具挑战性的竞赛之一、ACM竞赛要求参赛者在规定的时间内,根据给出的问题,编写出能在规定时间内运行并给出正确答案的程序。
参加ACM竞赛不仅可以锻炼算法思维,提高编程实力,还可以拓宽知识领域和增加竞争力。
在这个ACM基础算法入门教程中,我们将介绍一些常用的基础算法和数据结构,帮助初学者更好地理解和掌握ACM竞赛所需的算法知识。
一、排序算法排序算法是ACM竞赛中最常用的算法之一,能够帮助我们按照一定的规则将数据进行排序,从而解决一些需要有序数据的问题。
1.冒泡排序:通过多次比较和交换来实现,每次迭代将最大的值沉到最底部。
2.快速排序:选择一个基准元素将数组分为两部分,一部分都小于基准元素,一部分都大于基准元素,递归排序子数组。
3.归并排序:将数组不断二分,将相邻两个子数组排序后再合并成一个有序数组。
4.插入排序:从第二个元素开始,依次将元素插入已排序的子数组中。
二、查找算法查找算法可以帮助我们在一组数据中找到目标元素,从而解决一些需要查找特定数据的问题。
1.顺序查找:逐个扫描数据,直到找到目标元素或扫描结束为止。
2.二分查找:对已排序的数组进行查找,不断将数组二分直到找到目标元素的位置。
3.哈希查找:通过计算数据的哈希值找到对应的存储位置,实现快速查找。
三、字符串匹配算法字符串匹配算法可以帮助我们在一组字符串中寻找特定模式的子字符串,从而解决一些需要在字符串中查找其中一种规律的问题。
1.暴力匹配算法:对目标字符串的每个位置,逐个将模式串进行匹配,直到找到或匹配结束为止。
2.KMP算法:通过已匹配的部分信息,尽量减少字符比较的次数。
3. Boyer-Moore算法:通过预先计算模式串中每个字符最后出现位置的表格,以及坏字符规则和好后缀规则,来实现快速匹配。
ACM 程序设计竞赛入门:第6讲 分治策略
✓ T(n)=O(nlog3) =O(n1.59) 较大的改进
为了降低时间复杂度,必须减少乘法的次数。
1. XY = ac 2n + ((a-b)(d-c)+ac+bd) 2n/2 + bd
2. XY = ac 2n + ((a+b)(c+d)-ac-bd) 2n/2 + bd
细节问题:两个XY的复杂度都是O(nlog3),但考虑到a+b,c+d可 能得到m+1位的结果,使问题的规模变大,故不选择第2种方 案。
一个小孩得到了装有16个金币的袋子。 这16个金币中有一个是伪造的。伪造的 金币比真的金币要轻。小孩的任务是用 一台可以比较两组重量的一起,找出伪 造的金币。 怎样才能快速找出呢? 帮帮他吧。
2020/12/10
3
所谓“分治策略 ” :
(1)一个大问题可以分成两个或多个更小 的问题;
(2)小问题通常与原问题相似,可以通过 递归求解;
大整数的乘法
请设计一个有效的算法,可以进行两个n位大整数的乘法运算
小学的方法:O(n2)
效率太低
分治法: O(n1.59)
✓较大的改进
更快的方法??
➢如果将大整数分成更多段,用更复杂的方式把它们组合起来, 将有可能得到更优的算法。
➢最终的,这个思想导致了快速傅利叶变换(Fast Fourier Transform)的产生。该方法也可以看作是一个复杂的分治算法。
(3)快速排序 在快速排序中,记录的比较和交换是从两端向 中间进行的,关键字较大的记录一次就能交换 到后面单元,关键字较小的记录一次就能交换 到前面单元,记录每次移动的距离较大,因而 总的比较和移动次数较少。
ACM基础算法入门及题目列表
ACM基础算法⼊门及题⽬列表对于刚进⼊⼤学的计算机类同学来说,算法与程序设计竞赛算是不错的选择,因为我们每天都在解决问题,锻炼着解决问题的能⼒。
这⾥以T ZOJ题⽬为例,如果为其他平台题⽬我会标注出来,同时也欢迎⼤家去访问,探索新平台去提⾼⾃⼰基础部分ACM竞赛随机性会⽐较⼤,所以新⼿请掌握好基础,基础不牢,地动⼭摇(⼤⼀上)1. C语⾔题包括T ZOJ1452在内的60道C语⾔实验题,2. 暴⼒枚举 3449 5125 4604 26263. 递归 14834. 模拟 1093 3715 3726 3727 4391 11485. 构造这种题往往在CF中会遇到,⽐如,刷题集点,就是都是英⽂题进阶T ZOJ200题以后可以尝试着去刷⼀些简单的算法(⼤⼀上以及⼤⼀下)1. 前缀后缀和 1532 42622. 5629 1597 1041 3044(⼆分100次)3. 排序(归并排序) 24524. 贪⼼ 1332 5059 1004 3110 44935. dfs 2777 4408 4833 3104 33606. bfs 3533 1335 1748 3031常⽤数据结构和算法T ZOJ300题以后可以尝试着去刷⼀些简单的算法和数据结构,要参加天梯赛就得刷会了,可以上 (⼤⼀下以及⼤⼆上)1. 并查集 1299 1278 1540 1612 1638 1840 1856 2574 2647 2648 2649 2769 3136 3197 3246 3274 3644 3645 3649 3660 4692 49152. 最短路(Floyd Dijkstra Bellman-Ford[SPFA])3. 最⼩⽣成树(Kruskal Prim) 1300 5263 2371 2415 3451 2737 28154. stl的应⽤5. 拓扑排序算法⼊门T ZOJ500题左右就可以⼊门算法了,在省赛中往往⽤得到。
ACM程序设计算法原理和ACM入门教材
计算机科学基础知识回顾
回顾计算机科学的基础知识,包括数据类型、变量、控制结构等。
数据结构和算法的关系
解释数据结构和算法之间的关系,如何选择适合特定问题的数据结构来提高 算法效率。
常见数据结构:数组、链表、栈、队 列
数组
存储一组相同类型的元素,支持随机访问 和修改元素。
栈
后进先出的数据结构,支持快速插入和删 除操作。
博弈论的基本概念和算法
介绍博弈论的基本概念和解决方法,如最大最小化、alpha-beta剪枝等。
计算几何基础知识
讲解计算几何的基本概念和算法,如点、线、面的表示和计算。
动态数据结构的应用
探讨动态数据结构的应用,如平衡二叉树、哈希表等。
字符串和图的高级算法
介绍字符串和图的高级算法,如正则表达式匹配、最小割最大流等。
排序算法的分类和性能分析
1 分分类排序
根据排序算法的思想和实现方式进行分类。
2 性能分析
评估不同排序算法的时间和空间复杂度。
快速排序和归并排序
1
归并排序
2
基于分治法,通过将序列分为两部 分并对每部分进行排序,然后归并
排序。
快速排序
基于分治法,通过比较和交换元素 实现排序。
算法分析和复杂度
介绍算法分析的基本概念和复杂度表示方法,如时间复杂度和空间复杂度。
高精度计算的应用
讲解高精度计算的基本原理和应用场景,如大整数运算、浮点数精度等。
高级算法的问题、优化和扩展
讨论高级算法的常见问题、优化技巧和算法扩展,如分支限界法、动态规划优化等。
好的编程习惯和技巧
分享好的编程习惯和技巧,如代码规范、调试技巧等。
经典题目和解题思路
ACM 程序设计竞赛入门:第4讲 简单数据结构
2020/12/10
3
1. 并查集
1.1 引例
输入格式 (Input Format):
输入的第一行是一个整数N(2<=N<=1000),表 示强盗的个数(从1编号到N)。 第二行 M(1<=M<=5000),表示关于强盗的信息条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敌人 。输入数据保证不会产生信息的矛盾。
合并
将两个元素所在的集合合并为一个集合。 通常来说,合并之前,应先判断两个元素是否属于同一集
合,这可用上面的“查找”操作实现。
2020/12/10
10
实现方法(1)
用编号最小的元素标记所在集合; 定义一个数组 set[1..n] ,其中set[i] 表示 元素i 所在的集合;
i 1 2 3 4 5 6 7 8 9 10
count ++; printf("%d\n",count); } }
示例—宗教信仰
题目链接
• 世界上有许多不同的宗教,现在有一个你感兴趣的问题 :找出多少不同的宗教,在你的大学中的大学生信仰了 多少种不同的宗教。
• 你知道在你的大学有n个学生(0<n<= 50000)。若直 接问每一个学生的宗教信仰不大适合。此外,许多学生 还不太愿意说出自己的信仰。有一种方法来避免这个问 题,询问m(0<=m<=n(n- 1)/ 2)对学生,询问他们 是否信仰同一个宗教(比如,可以询问他们是否都参加 同一教堂)。从这个数据,您可能不知道每个人宗教信 仰,但是你可以知道有多少不同宗教信仰。你可以假设 ,每名学生最多信仰一个宗教。
ACM基础算法入门
辗转相除法
扩展欧几里得
双六 一个双六上面有向前向后无限延续的格子,每个格子都写有整数。其中0号格子 是起点,1号格子是终点。而骰子上只有 a , b , -a , -b 四个整数,所以根据 a 和 b 的值的不同,有可能无法到达终点。 格子如下: …… -4 -3 -2 -1 0 1 2 3 4 …… 掷出四个整数各多少次可以到达终点?输出任意一组解。 1<= a , b <=10^9
0 1 0 0 1
解题过程
本题是简单的搜索问题,采用深度优先 遍历可以解决,根据题目要求,假设从 任意一点值为'1'的出发,将这点的坐标 上下左右全部用'0'替换,1次DFS后与初 始动这个'1'连接的'1'全部被替换成'0', 因此,直到图中不再存在'1'为至,总共 进行的DFS的次数就是最后的结果咯!那 么,根据题目要求,有4个方向,时间复 杂度为O(4*n*m)。
例题:
水池数目 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池, 假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在, 你的任务来了,请用计算机算出该地图中共有几个水池。 输入m行每行输入n个数,表示此处有水还是没水 (1表示此处是水池,0表示此处是地面) 0<m<100 0<n<100 输入: 34 1000 0011 1110 输出: 2 输入: 55 1111 0010 0000 1110 0011 输出: 3
把各区间按照a从小到大顺序。如果区间1的起点不是s, 则无解,即[s,t]无法被完全覆盖(因为其他区间的起点更大, 不可能覆盖到s点),否则选择起点在s的最长区间。选择此 区间[ai,bi]后,新的起点应该被设置为bi,并且忽略所有区间在 bi之前的部分,就像预处理一样。虽然贪心策略比上面的题 复杂,但是仍然只需要一次扫描。如下图5所示。s为当前有 效起点(此前部分已被覆盖),则应该选择区间2。
ACM 程序设计竞赛入门:第1讲 快速入门
11
Sample Input 2 15 10 20
Sample Output 6 30
2020/12/10
12
Hdoj_1090源代码:
#include <stdio.h> int main() {
int n,i,a,b;
scanf("%d",&n);
for(i=0;i<n;i++) {
scanf("%d %d",&a, &b); printf("%d\n",a+b); } }
2020/12/10
24
说明(5_2):cin.getline的用法:
getline 是一个函数,它可以接受用户的输入的字符,直到已达 指定个数,或者用户输入了特定的字符。它的函数声明形式( 函数原型)如下:
istream& getline(char line[], int size, char endchar = '\n');
/showproblem.php ?pid=1094
2020/12/10
19
Input contains an integer N in the first line, and then N lines follow. Each line starts with a integer M, and then M integers follow in the same line.
202
输入不说明有多少个Input Block,以EOF 为结束标志。 参见:HDOJ_1089
/showproblem.php ?pid=1089
2020/12/10
ACM 程序设计竞赛入门:第1讲 快速入门
2020/12/10
13
本类输入解决方案:
C语法:
scanf("%d",&n) ;
for( i=0 ; i<n ; i++ ) {
.... }
C++语法:
cin >> n;
for( i=0 ; i<n ; i++ )
{
....
}
2020/12/10
14
输入(3):
输入不说明有多少个Input Block,但以某 个特殊输入为结束标志。 参见:本校OJ1000
第一讲 快速入门
2020/12/10
1
ACM题目特点:
严格的输入、输出格式;有偏差则不能AC;
追求高效简洁的算法 。即便算法是正确的, 但策略过于复杂,会导致超时;
测试数据庞大;即便算法是正确的,如果在程 序实现时出现误差都会被严密的测试数据查出 而把程序判定为错误的;
强调解决实际问题的能力。赛题与实际应用的 联系很紧密,很多试题被出题者描述成一个有 趣的故事。因此,读题能力、分析能力相当重 要。
2020/12/10
4
困惑:用C/C++的输入/输出?
一般来说,差别不是太大,习惯就好; cin,cout 使用方便;scanf, printf 控制灵 活,在效率上有优势; 不要混用。 千万不要把cout和printf混用,因为cout 是带缓冲的而printf不带,所以会使得输 出的数据顺序混乱。
8
本类输入解决方案:
C语法:
while(scanf("%d %d",&a, &b) != EOF)
ACM算法 计算几何基础ppt课件
57 2020/4/15
58 2020/4/15
59 2020/4/15
60 2020/4/15
61 2020/4/15
62 2020/4/15
63 2020/4/15
64 2020/4/15
特别提醒:
以上介绍的线段的三个属性, 是计算几何的基础,在很多方 面都有应用,比如求凸包等等, 请务必掌握!
15 2020/4/15
第二单元
多边形面积 和重心
16 2020/4/15
基本问题(1):
给定一个简单多边形,求其 面积。
输入:多边形(顶点按逆时 针顺序排列)
输出:面积S
17 2020/4/15
A=sigma(Ai) (i=1…N-2)
P1
A1 P2
P6 A4
P5 A3
A2 P4
P3
25 2020/4/15
凹多边形的面积?
P3
P2 P4
P1
26 2020/4/15
依然成立!!!
多边形面积公式:A=sigma(Ai) (i=1…N-2)
结论: “有向面积”A比“面积”S其实更本
质!
27 2020/4/15
思考如下图形:
18 2020/4/15
Any good idea?
19 2020/4/15
先讨论最简单的多边形——三角形
20 2020/4/15
三角形的面积:
在解析几何里, △ABC的面积可以通过 如下方法求得:
点坐标 => 边长 => 海伦公式 => 面积
21 2020/4/15
思考:此方法的缺点:
C=sigma((↑Pi +↑Pi+1)(↑Pi ×↑Pi+1) ) /(6A)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
辗转相除法
扩展欧几里得
双六 一个双六上面有向前向后无限延续的格子,每个格子都写有整数。其中0号格子 是起点,1号格子是终点。而骰子上只有 a , b , -a , -b 四个整数,所以根据 a 和 b 的值的不同,有可能无法到达终点。 格子如下: …… -4 -3 -2 -1 0 1 2 3 4 …… 掷出四个整数各多少次可以到达终点?输出任意一组解。 1<= a , b <=10^9
例题
给定整数 a1,a2,a3,......,an, 判断是否可以从中选出若干个数,使 他们的和恰好为k。 限制条件: 1<=n<20 -10^8<=ai<=10^8 -10^8<=k<=10^8
输入: 4 1,2,4,7 13 输出: Yes 输入: 4 1,2,4,7 15 输出: No
解题过程
i=0 sum=0
+1
i=1 sum=0 i=1 sum=1
+2
i=2 sum=0 i=2 sum=2
+4
i=3 sum=2 i=3 sum=6
从a1开始按 顺序决定每 个数加或不 加,在全部 n个数决定 后在判断他 们的和是不 是k即可。
宽度优先搜索
宽度优先搜索(BFS,Breadth-First Search)也是搜索的手段之一。与深 度优先搜索类似,从某个状态出发探索所有可以到达的状态。 与深度优先搜索的不同在于搜索的顺序,宽度优先搜索总是先搜索距离 初始状态近的状态,也就是说它是按照开始状态--->只需1次转移就可到 达的所有状态--->只需2次转移就可到达的状态--->......,这样的顺序进 行搜索。对于同一状态,宽度优先搜索只经过一次,因此复杂度为O (状态数*转移的方式)。 根据宽度优先搜索的特点,采用队列进行实现。
输入: 4,11 输出: 3001
解题过程
这个问题用数学语言表述就是:“求整数 x 和 y 使得 ax + by =1”。 可以发现如果gcd(a,b)!=1,无解。反之,则可以通过扩展辗转相除法来求 解。 设 a>b。 1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0; 2,ab!=0 时 设 ax1+by1=gcd(a,b); bx2+(a mod b)y2=gcd(b,a mod b); 根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b); 则:ax1+by1=bx2+(a mod b)y2; 即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2; 根据恒等定理得:x1=y2; y1=x2-(a/b)*y2; 这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2. 上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
s
基础的“穷竭搜索”
概念: 穷竭搜索是指将所有的可能性罗列出来, 在其中寻找答案的方法。
这里,我们主要介绍: 深度优先搜索 宽度优先搜索
深度优先搜索
深度优先搜索(DFS,Depth-First Search)是搜索的手段之一。 它从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步 的状态,继续转移到其他状态,如此不断重复,直至找到最终的解。 根据深度优先搜索的特点,采用递归函数实现比较简单。
【分析】 本题的突破口仍然是区间包含和排序扫描,不过要先 进行一次预处理。每个区间在[s,t]外的部分都应该预先被切 掉,因为它们的存在是毫无意义的。例如要覆盖线段[3,5], 闭区间[0,1]的存在无意义。在预处理后,在相互包含的情况 下,小区间显然不应该被考虑。
解题思路
会场安排问题
先对n个区间按照bi从小到大的顺序排序,如果 bi相同,则ai按照从大到小的顺序排序。然后从前往后 扫描每个区间,找出所有的符合条件的区间。
注意:排序后第一个区间一定会选,因为它的bi 最小, 它不影响后面区间的选取,而且如果不选此区间,最 终 求出的区间数目会变少。
区间选点问题
数论那些事
数学,特别是数论与计算机科学有着密 切的联系,所以也常被选作题材。虽然 数学问题大多需要使用特定方法求解, 但其中有几个基础算法扮演着重要的角 色。
数论基础
辗转相除法
1、求最大公约数 2、扩展欧几里得 3、ax+by=gcd(a,b) 1、埃氏筛法 2、区间筛法
有关素数的基础算法 快速幂
V [ i-1 ] [ j ] += V [ I ] [ j ] > v [ I ] [ j + 1 ] ? V [ I ] [ j ] : v [ I ] [ j + 1 ];
单调递增非降子序列
给定一整型数列{a1,a2...,an} (0<n<=100000),找出单调递增最长 子序列,并求出其长度。
例题:
水池数目 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池, 假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在, 你的任务来了,请用计算机算出该地图中共有几个水池。 输入m行每行输入n个数,表示此处有水还是没水 (1表示此处是水池,0表示此处是地面) 0<m<100 0<n<100 输入: 34 1000 0011 1110 输出: 2 输入: 55 1111 0010 0000 1110 0011 输出: 3
如:1 9 10 5 11 2 13的最长单调递增子 序列是1 9 10 11 13,长度为5。
解题思路
定义状态 dp【i】以i为结束节点最长单调子序列长度 阶段 每一个点选择过程即阶段 转移方程: Dp【i】= max(dp【1~(i-1)】) + 1 想想有没有更好的方法???
dp总结
数轴上有n个闭区间[ai, bi]。取尽量少的点,使得每个 区间内都至少有一个点(不同区间内含的点可以是同一个)。
【分析】 如果区间i内已经有一个点被取到,我们称此区间已经被 满足。受上一题的启发,我们先讨论区间包含的情况。由于 小区间被满足时大区间一定也被满足。所以在区间包含的情 况下,大区间不需要考虑。 因此,我们把所有区间按b从小到大排序(b相同时a从 大到小排序),则如果出现区间包含的情况,小区间一定排 在前面。第一个区间应该选取哪一个点呢?正确的贪心策略 是:取最后一个点。如下图。
埃氏筛法
给定整数n,请问n以内多少个素数 n<=10^6 输入 25 输出 9
解题思路
要枚举n以内素数,可以用埃氏筛法 列出2以后的所有序列: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 标出序列中的第一个素数,也就是2,序列变成: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2 将剩下序列中,划摽2的倍数,序列变成: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 4 6 8 10 12 14 16 18 20 22 24 (划出的数) 如果现在这个序列中最大数小于最后一个标出的素数的平方,那么剩下的序列中所有的数都是 素数,否则回到第二步。 本例中,因为25大于2的平方,我们返回第二步: 剩下的序列中第一个素数是3,将主序列中3的倍数划出,主序列变成: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 4 6 8 9 10 12 14 15 16 18 20 21 22 24 (划出的数) 我们得到的素数有:2,3 25仍然大于3的平方,所以我们还要返回第二步: 现在序列中第一个素数是5,同样将序列中5的倍数划出,主序列成了: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 4 6 8 9 10 12 14 15 16 18 20 21 22 24 25 (划出的数) 我们得到的素数有:2 3 5 。 因为25等于5的平方,跳出循环. 结论:去掉数字,2到25之间的素数是:2 3 5 7 11 13 17 19 23。
ACM基础算法入门
.基础动态规划 .基础的“穷竭搜索” .贪心的三种区间问题 .数论那些事 .二分的另类法
引言
算法简单但思想及其重要 介绍的算法都堪称为经典中的经典
基础动态规划
多阶段决策过程最优化的数学方法 三要素: -阶段 -决策 -状态
动态规划的适用范围
最优子结构(最优化原理) 当前状态依赖于前面的状态得到,是前面 状态的完美总结
把各区间按照a从小到大顺序。如果区间1的起点不是s, 则无解,即[s,t]无法被完全覆盖(因为其他区间的起点更大, 不可能覆盖到s点),否则选择起点在s的最长区间。选择此 区间[ai,bi]后,新的起点应该被设置为bi,并且忽略所有区间在 bi之前的部分,就像预处理一样。虽然贪心策略比上面的题 复杂,但是仍然只需要一次扫描。如下图5所示。s为当前有 效起点(此前部分已被覆盖),则应该选择区间2。
无后效性(不成环)
经典模型