收藏 分享(赏)

回到起点种突破性思维.doc

上传人:lxhqcj 文档编号:6829056 上传时间:2019-04-23 格式:DOC 页数:11 大小:124.72KB
下载 相关 举报
回到起点种突破性思维.doc_第1页
第1页 / 共11页
回到起点种突破性思维.doc_第2页
第2页 / 共11页
回到起点种突破性思维.doc_第3页
第3页 / 共11页
回到起点种突破性思维.doc_第4页
第4页 / 共11页
回到起点种突破性思维.doc_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、CTSC2005 国家集训队论文第 1 页 共 11 页 回到起点一种突破性思维关键字 起点 类比 分离集合森林摘要高层次的信息学竞赛已经不是单纯一个算法、一种数据结构间的较量,而是对思维方法、创新能力的考验。本文旨在深刻剖析一种突破性思维回到起点,亦即敢于放弃当前成果,回到初步分析处展开理性思考的可贵品质。本文第一章提出一个已被经典算法解决的普通题。第二章对这道题展开讨论,简述了经典的解决方案,而后模拟本文主线描绘的思维方式进行思考,提出一个被遗忘的简单算法,并进行优化和类比,精确计算复杂度后问题被完美解决。第三章对本思维方式在两个例题中的应用作了对比和升华,辩证地以前进性和曲折性的统一阐述

2、了这类思想的重要性。CTSC2005 国家集训队论文第 2 页 共 11 页 目录1 问题的提出1.1 问题描述1.2 问题的初步分析离散化1.3 一个朴素的想法2 问题的解决2.1 经典算法2.2 另类算法2.3 通过完整的路径压缩完善算法2.4 秩的建立2.5 小结3 总结CTSC2005 国家集训队论文第 3 页 共 11 页 正文1 问题的提出1.1 问题描述 USACO 2.1 Shaping Regions 改编N 个不同颜色的不透明长方形(1N3000)被放置在一张长宽分别为A、B 的白纸上。这些长方形被放置时,保证了它们的边与白纸的边缘平行。所有的长方形都放置在白纸内,所以我们

3、会看到不同形状的各种颜色。坐标系统的原点(0,0) ,设在这张白纸的左下角,而坐标轴则平行于纸边缘。输入:第 1 行:A , B 和 N, 由空格分开。第 2N+1 行:按照从下往上的顺序,每行输入的是一个长方形的放置。为五个数 llx, lly, urx, ury, color 这是长方形的左下角坐标,右上角坐标和颜色。其中 color 为整数。0=llx,urx=A,0=lly,ury=B。所有坐标(包括 A、B)都是 0 至 109 的实数。颜色 1 和底部白纸的颜色相同。输出:输出文件应该包含一个所有能被看到颜色连同该颜色的面积(保留小数点后三位)的列表(即使颜色的编号不是连续的) 。

4、按 color 的增序顺序输出,不要输出面积为 0 的颜色。样例输入:20 20 32 2 18 18 20 8 19 19 38 0 10 19 4样例输出1 91.0002 84.0003 187.0004 38.0001.2 问题的初步分析离散化自 IOI1998 的 Picture 问题始,和平面放置矩形有关的问题已在信息学竞赛中屡见不鲜,其最基本的预处理操作是将平面离散化。如图 1CTSC2005 国家集训队论文第 4 页 共 11 页 1 2 3 4 5 6123456图 1将平面理解成网格,也就是说将所有在矩形坐标中出现过的 x 坐标(y 坐标)提出,排序后删除重复,并按顺序编号

5、。任意两个相邻格点连成的线段,称之为“元线段 ”;两个相邻离散过的 x 坐标(y 坐标)之间的区域,称之为 “离散列”(“离散行” ) ;任意一个离散行和离散列的公共部分称之为“离散格” 。对每个矩形坐标相应地存在一个格点坐标与之对应。这有助于处理坐标为实数,或者范围超过 longint 的问题。离散化之后,任意矩形顶点坐标均可表示为 1 到 2N 之间的整数:利用 hash 策略可以将实数坐标在 O(1)时间内转化为对应的整点坐标,更显然地,直接读表可以在 O(1)时间内将格点坐标转化为原矩形坐标。因此后文只考虑坐标为整数,且范围在 1 到2N 之间的 N 个格点矩形的问题。1.3 一个朴素

6、的想法最朴素算法的实现取自于简单的灌水(Floodfill)算法。就是用 2Nx2N 的数组,分别记录每个离散格的颜色,初始时全部无色。自顶至下处理每一个矩形,将其覆盖之下无色的部分全部填上颜色。考虑到空间可能无法承受,改进的措施是每次处理一个离散行(2N 的一维数组) ,自顶向下处理每个矩形,如果这个矩形与当前离散行有公共部分,那么就和前面类似地,将无色部分涂色,如图 2:CTSC2005 国家集训队论文第 5 页 共 11 页 当前离散行当前离散行当前离散行图 2该方法基本不会增加程序运行时间,只是时间复杂度系数稍微增加了些,并不影响大局。2 问题的解决2.1 经典算法解决这类问题的经典算

7、法莫过于线段树。同样是对每个离散行做处理,该算法利用了 O(N)空间的树型数据结构。如图 3,构建一个线段树:1,101,5 5,101,3 3,5 5,7 7,101,2 2,3 3,4 4,5 5,6 6,7 7,8 8,108,9 9,10图 3该数据结构主要支持的操作是,给定线段l,r和属性 X 组成的操作对(l,r,X),意思是将区间l,r赋予属性 X。称“ 在 P 节点上进行(l,r,X)操作”为 P(l,r,X),具体操作如下:CTSC2005 国家集训队论文第 6 页 共 11 页 Operation P(l,r,X)If l,r与当前节点 P 对应的区间交集为空 Then R

8、eturnIf l,r可以完全覆盖当前结点 P 对应的区间Then 将属性 X 记录在该结点Else 依次对 P 的左右子结点操作 P.leftchild(l,r,X), P.rightchild(l,r,X)End IfEnd Operation例如图 3 中红色的部分是处理 Root(3,8,X)操作后被赋予 X 属性的结点。可以证明对每个操作 Root(l,r,X),其时间复杂度为 O(logN)(N 是叶结点个数,也就是区间范围) 。观察本题需要这个数据结构支持怎样的特殊操作:1、插入一条颜色为 X 的线段l,r,该区间l,r 上原有颜色不被替换,其余部分染上颜色 X。2、返回所有颜色

9、当前的覆盖量。 (该操作只将在该离散行处理完毕后一次性调用)操作 2 只需将线段树全部遍历一遍即可求得,时间复杂度 O(N)。至于操作1,对线段树上的每条线段标记颜色不是难事儿,只需要将前文所述的属性 X定义其为 color flag,用来标记颜色。因此主要难点在于不破坏区间上的已有颜色。其实这一点也不难实现,类似地我们给出这个操作的具体过程:Operation P(l,r,X)If l,r与当前节点 P 对应的区间交集为空 Then ReturnIf 节点 P 已经被某种颜色覆盖 Then ReturnIf l,r可以完全覆盖当前结点 P 对应的区间Then 将颜色 X 记录在该结点Else

10、 依次对 P 的左右子结点操作 P.leftchild(l,r,X), P.rightchild(l,r,X)End IfEnd Operation至此该算法的空间复杂度为 O(N),时间复杂度为 O(N2logN),在某种程度上是一个可以通过本题数据的优秀算法。2.2 另类算法避开繁文缛节,我们回到起点,分析一下原始算法,就是“1.3 一个朴素的想法”内的算法。有效解决问题往往有两条途径,一个是使用高级算法或数据结构,另一个就是分析原有的算法或数据结构,找出冗余进行针对性改进。回顾一下之前的算法CTSC2005 国家集训队论文第 7 页 共 11 页 当前离散行当前离散行当前离散行图 4灰色

11、部分是不必要的检索迅速找到冗余:处理当前线段(矩形与当前离散行的交集)时,对已经覆盖的线段,不能迅速避开,需要无畏的比较。改进措施如下:设立 next 数组,初始时 nexti=i+1;另还有 color 数组,colori 记录该离散行的第 i 个离散格当前的颜色。设当前插入的线段为 l,r,即占用编号为 l 至 r-1的离散格:1. il2. 查看 colori,如果它未被着色,那么将其着色。3. 移动指针 inexti,并记录指针经过的位置。4. 如果 i 指针没有越过边界 r-1,跳转 2,否则跳转 5。5. 将所有指针经过位置 x 的 nextx置为 nextr-1。下面的图 5 将

12、给出一组覆盖的例子:(插入的线段与图 4 稍有类似)第一次用颜色 1 的线段覆盖2,6) ,因为 next 数组完全是初始值,因此 i 指针从 l=2 一直移动到 i=r,color25 被置为颜色 1, next25被置为 nextr-1=r=6。第二次用颜色 2 的线段覆盖4,7),i 指针来到 l=4, color4不被修改,inexti = next4 = 6。接下来 color6被修改,指针移动到 next6=7=r,移动完毕。指针经过了 4,因此 next4被置为 nextr-1=r=7。第三次用颜色 3 的线段覆盖1,9),i 指针先来到 1,修改 color1,inexti来到

13、 2,观察到 color2已经有颜色以后先后转战 inext2=6,i next6=7。至此可以修改 color7以及 color8,并且最终在 i=9 的时候停止。过程中 next1、next2、next6、next7都需要被修改为 next8=9。CTSC2005 国家集训队论文第 8 页 共 11 页 i 1 2 3 4 5 6 7 8nexti 2 3 4 5 6 7 8 9colori NIL NIL NIL NIL NIL NIL NIL NIL颜色 1覆盖2,6) i 1 2 3 4 5 6 7 8nexti 2 6 6 6 6 7 8 9colori NIL 1 1 1 1 N

14、IL NIL NILi 1 2 3 4 5 6 7 8nexti 2 6 6 7 6 7 8 9colori NIL 1 1 1 1 2 NIL NIL颜色 2覆盖4,7)i 1 2 3 4 5 6 7 8nexti 9 9 6 7 6 9 9 9colori 3 1 1 1 1 2 3 3颜色 3覆盖1,9)图 5观察上述算法,其精髓在于将已染色的相邻离散格合并,或者对其“预定”合并,也就是做上标记,使其在以后的处理中自动合并平摊思想。这一想法源于“带路径压缩按秩合并的分离集合森林” ,也就是高效的俗称 “并查集”算法。注意到当前算法并未完全进行路径压缩,而且没有按秩合并,因此该算法有待完善

15、。 (其实可以证明本算法在大部分情况下时间复杂度维持在 N2 左右,不易退化)2.3 通过完整的路径压缩完善算法将相邻的已染色线段看成一个集合,这样在l,r)的检索过程中,遇到已染色线段可以大跨步跨越。我们的目标是让这个跨越在平摊 O(1)的时间内完成。算法改进如下:设立 next 数组,初始时 nexti=i+1;同时设立 p 数组,初始时 pi=i(p 数组类似并查集算法中的父节点指针) ;另还有 color 数组,colori记录该离散行的第 i 个离散格当前的颜色。设当前插入的线段为 l,r,即占用编号为 l 至 r-1的离散格:1. il2. 查看 colori,如果它未被着色,那么

16、将其着色。3. 将当前指针位置记录4. 如果 i 指针已经越过边界 r-1,跳转 75. 如果 pi!=i,ipi;否则 inexti。6. 跳转 27. 将所有指针经过位置 x 的 px置为 pr-1,nextx置为 nextr-1。为了建立分离集合森林,我们作如下定义:1、用 i 代表编号为 i 的节点CTSC2005 国家集训队论文第 9 页 共 11 页 2、将 pi定义为节点 i 的父节点3、父节点为自身的节点定义为根节点。注意:对于 pi!=i 的节点,也就是分离集合森林中的非根节点,其 nexti已经失去意义。而对于根节点,必然有 nexti = i+1。这一点将为 2.4 节服

17、务。与图 5 相同,这里仍对上文数据给出图示及文字解释(因为 next/color 的定义与2.2 类似,因此对其改变我们不多赘述,将重点放在分离集合森林的构建):i 1 2 3 4 5 6 7 8p 1 2 3 4 5 6 7 8nexti 2 3 4 5 6 7 8 9colori NIL NIL NIL NIL NIL NIL NIL NIL1 2 3 4 5 6 7 812 3 46 7 85颜色 1覆盖2,6)颜色 2覆盖4,7)颜色 3覆盖1,9)1247 85i 1 2 3 4 5 6 7 8p 1 5 5 5 5 6 7 8nexti 2 6 6 6 6 7 8 9colori

18、 NIL 1 1 1 1 NIL NIL NILi 1 2 3 4 5 6 7 8p 1 5 5 6 6 6 7 8nexti 2 6 6 7 7 7 8 9colori NIL 1 1 1 1 2 NIL NIL36i 1 2 3 4 5 6 7 8p 8 8 5 6 8 8 8 8nexti 9 9 6 7 9 9 9 9colori 3 1 1 1 1 2 3 312478536图 6CTSC2005 国家集训队论文第 10 页 共 11 页 第一次用颜色 1 的线段覆盖2,6) ,因为所有节点自成集合,故本次覆盖操作将 25 节点合并,5 为他们的根节点(代表元) ,显然 next24

19、失去其意义(在表格中用 X 表示) 。第二次用颜色 2 的线段覆盖4,7),i 指针来到 l=4,根据分离集合森林的定义,需要找到其所在集合的根节点(该集合的代表元) ,也就是节点 p4=5。紧接跳转下一个集合,也就是节点 6。指针 i 移动到 6,并且修改 color6。最后压缩路径前面所经过的所有点 x 的 px都指向 65 和 6 所在的集合合并,6 成为新的根节点 。第三次用颜色 3 的线段覆盖1,9),i 指针先来到 1,修改 color1后跨入next1=2 所在的集合,发现其已染色,通过 ipp2=6 以及 inexti=7 跨越该集合,并对 7、8 两个独立的集合染色。最后 1

20、、2、7、8 所在集合进行总合并。8 为新的集合的根节点(代表元) 。2.4 秩的建立所谓秩,就是一个集合(树)所含的节点个数。对分离集合的合并,采取将节点数多的集合( 树) ,附着在节点数少的集合(树) 上的策略,可以将集合的合并复杂度降至平摊的 O(1)。这一个过程需要在上文蓝色粗斜体部分,即确定合并后新根节点的部分稍加修改,选取秩最大的树根作为新的根节点(代表元)即可。注意到这时对根节点不一定有 nexti = i+1。一共有最多 2N 个集合,合并次数不超过 2N-1,对当前离散行的处理时间复杂度仅为 O(N),整个算法的时间复杂度为 O(N2)。2.5 小结摒弃当今主流的线段树算法,

21、回到起点,对朴素算法进行改进的思想实属不易。但其后算法的完全建立,思维过程极其缜密:首先找到冗余进行修改,旨在量变某种意义上提高算法对部分数据的运行效率;发现算法的优越之处后,展开类比,将类似数据结构、算法的自身优点吸取,并进行改进;最后大步伐迈向让算法复杂度质变的目标。3 总结希腊传说弗里吉亚国国王打了一个戈尔迪之结,预言称能解开它的人将统治整个亚洲。亚历山大大帝认为它在预言中找到了自己的命运归宿,拿起长剑,径直将结劈开。有人说亚历山大将绳劈开是“作弊”的行为,但或许奥林匹斯山诸神寻找的就是如此少说多做的决断力?面对多元化的世界,我们总会有这种“答案意识过强”的状态,就是这种倾向:对答案进行

22、快速的设想,迅速沿那条道兴高采烈地出发,却并没在意先前设想的正确性、全面性。被自己创造的无形障碍蒙蔽实乃可惜,因此我们不能因片面的认识,或对放弃眼前利益的恐惧而裹足不前,偶尔我们也需要此类果敢与魄力。这正是前进性和曲折性的统一。问题的表示往往比答案更重要,答案不过乃数学或实验。要提出新的问题、新的可能性、从某个新的角度考虑一个旧问题,都要求创造性的想象力,回到起点对问题重新定义,这才是真正的科学进步之所在。CTSC2005 国家集训队论文第 11 页 共 11 页 参考资料i. Introduction to Algorithmsby Thomas H. Cormen, Charles E.

23、Leiserson, Ronald L. Rivest, Clifford Steinii. The Art of Computer Programmingby Donald E. Knuthiii. The Computer Science and Engineering Handbookby Allen B. Tucker, etc.iv. 实用算法的分析和程序设计by 吴文虎 王建德v. http:/get-me.to/oi 辛韬同学提供的 BalticOI2004 解答感谢1、感谢辽宁省的辛韬同学对我的大力帮助(包括部分算法和证明) 。2、感谢江苏省青少年信息学(计算机)奥赛委员会教练组全体老师对我的指导。3、感谢我的母校江苏省南京市外国语学校的老师给我的支持。4、感谢我的家人给我的关怀。5、感谢所有的信息学好友!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报