去年Final在上海举办时我已经退役,所以没有参加。不过我当时看了比赛的直播,并也看了一下题目。我刚刚又重新看了一下题目,写了一篇对题目算法的简要分析,在此与大家探讨。

 

Problem A

这是一道难题,比赛中几乎所有的队避开了这题。虽说是一个模式识别,但图像可以放大,非常不好处理。可以根据pattern中平行线段间的距离来确定放大的倍数,然后再到图里面进行枚举匹配。但不仅要分情况讨论,还要注意精度。是一道算法和编程都十分繁琐的题目。

Problem B

本题是一个典型的综合题。模型本身是一个最短路,但加入了计算几何的背景。最短路的计算对于参加World Final的选手自然是小菜一碟,但此题中每条边的cost是什么?由题目的描述可知,每条边的cost是穿过的cell的个数。那么cell由什么来划分?每个tower对应的cell就是一个离这个tower比离其它tower都要近的区域。这样的区域是什么?学过计算几何的可能知道,所有的cell构成的一个平面划分是一个Voronoi图,Voronoi图可以在O(nlogn)的时间里求出。所以本题划分为两个步骤:一是求出Voronoi图并计算每条边的费用,二是计算最短路。

难点在于,Voronoi图的计算非常繁琐,我相信没有一支队愿意在比赛中写一个求Voronoi图的程序,所以我们要换一种方法。关键在于,怎样判断一个线段是否穿过了一个cell?每个cell都是一些由中垂线围成的凸多边形,如果穿过了这个cell,就必然会有交点,而这个交点一定是该线段和某条中垂线的交点。所以问题立刻变得简单:要计算线段AB是否穿过tower Pi的cell,只需要枚举PiPj的中垂线和AB的交点,再判断这个交点是否离Pi比所有其它Pj都近,如果存在这样的交点,则AB穿过Pi的cell。

这样子我们只需要一个求线段交点的routine即可,比起求Voronoi图,编程复杂度大大下降。而算法的时间复杂度也是可以接受的。

Problem C

虽然本题叫做Traveling Judges Problem,但却并不是一个TSP模型。仔细看一下就会发现这是一个Steiner Tree的模型,即给出一些Steiner节点,求一棵费用最小的连接所有Steiner点的树。Steiner Tree problem本是NP-hard,但此题最多20个点,规模甚小。

一般的搜索会超时,正确的做法是状态空间dp,即用一个二进制串标记各点的状态,这是topcoder中常用的技术了。

Problem D

这题首先要确定可能shuffle的次数。每次shuffle最多伴随一次交换,从而最多改变两个位置的数,因此n次shuffle后最多有2n个位置的数字不对。我们可以将得到的串跟n次shuffle不加交换的串相比较,如果不匹配的位置<=2n的话,那么n就是一个可能的shuffle次数。这样的n如果存在必然唯一。因为n<=10,所以不匹配的地方最多20个,也就是匹配的位置最少有32个。如果n1和n2同时满足匹配的位置>=32,那么公共匹配的位置就>=32+32-52=12。而不难验证,没有两个n对应的序列有超过12个位置的数字相同。

确定了shuffle的次数后,下一个难题就是如何确定交换的位置。可能的状态数呈几何级数增长,n次交换后最多可能产生52^n种不同的置换,枚举是不可能的。一种立刻出现的想法是用空间换时间,枚举m步之后可以得到的所有状态,存在一个hash table里面,然后对剩下的步数进行反向搜索再到hash table里面查找。这样子状态数下降到52^5,但仍然太大了,空间上难以承受。

我认为此题应该搜索剪枝。首先先考虑没有交换的情况,找出k次shuffle后的位置表。从这张表我们就可以知道,第i步的一次交换其实等价于第j步的某两个位置交换。这样子我们避免了对整个序列shuffle,而只用考虑交换产生的影响。

比如,第一次shuffle后,如果我们交换位置0和位置1,也就是说数字26和0,这其实等价于交换第二次shuffle后的位置1和位置3。假如我们已经求出shuffle总次数是k,那么问题就变成,每一次shuffle对应了51个对换和一个恒等置换,能否从k次中各取出一个对换,使得这些对换的乘积成为一个已知的置换。

不进行剪枝的话,运算量最多是52^10,难以承受;但每一步最多纠正两个位置,所以还剩t次shuffle的时候,如果错误的位置>2t,就可以回溯了。大部分的对换都会增加出错的位置。最坏的情况是shuffle=10而且错误的位置很少,此时平均5步之后也可以剪枝了,时间上可以承受。更强的一个剪枝是考虑轮换,一个k-轮换至少分解成k个对换的乘积,所以至少需要k次shuffle。搜索的时候,不要记录整个需要的置换,而是记录成不相交的轮换的积。这样一来节省了置换乘法的开销,二来方便剪枝。

由于我不知道具体数据如何,从而无法得知此算法是否能通过所有数据。如果还不足够的话,可以再进行下面一些剪枝:

一,可以进行预处理,计算反向shuffle k步后数字可能在的位置。

二,可以对于出错位置较少的情况另做处理。

我相信这样足以解出此题。

Problem E

简单的数学题。每个room对应的日照时间都是一个连续的区间。枚举并进行区间切割即可。

Problem F

此题坐标范围太大,首先要进行离散化。离散化后进行bfs即可。但算法实现上有很多的技巧。首先要清楚的认识到进行离散化得到一个网格后,哪些是边,哪些是点。我们是在边上移动还是在格子中移动?移动的费用是多少?由于穿过一条马路才会使得费用加1,这题不能直接进行bfs,而是要每次bfs得到一个费用的等价类,然后一层一层推进。可以采取的一种技巧是把坐标都乘2,把点和格子都对应成格子。还有一种好方法是把每个矩形染一种不同的颜色,bfs的时候,同色的格子就是互相可达的。

这两种方法都免去了线段的处理。当然了,如果不怕麻烦,用最直接的办法处理也是可行的。

这题也是一个很好的综合题。首先是压缩映射的一个离散化,然后进行bfs的时候还有多处难处理的细节。此题要简洁正确的实现远比想出算法困难,建议自己动手实现。

Problem G

这是本次比赛的压轴题,找了一个很困难的定理来出这个题目,本题与希尔伯特第18问题相关。虽说给了提示,但还是没有明确的可以入手的地方。比赛中几乎所有的队避开了这个题目。我没有细想这个题目,如果你有任何想法请告诉我。

Problem H

不少队伍用二分图赋权匹配解决这个问题。其实对于horizontal和vertical的情况都可以贪心,就是diagonal较为麻烦。这题只有15个点,即使匹配也不需要用经典的算法。直接进行状态空间dynamic programming即可,非常容易实现。

Problem I

每个workshop都从14点开始,所以一个room最多容纳一个workshop,从而是一个明显的二分图赋权匹配。由于有两个权,所以要先进行一个转化。

如果不是每个room只能容纳一个workshop的话,就变成了bin packing,不可能解决这么大规模的问题。

Problem J

也是简单题,枚举加上容斥原理。20 choose 10肯定小于2^20,m<=10,所以时间复杂度上可以接受。本题用位运算实现非常方便。

总结

难度上,除了A,D,G三题,其它都不算难。一支优秀的队伍应具备做出7题的实力,而能做出8题的则是世界级。考虑到现场发挥对选手的影响,做出7题已是不易。最后结果,上海交大解决D题,是唯一一支做出8题的队,从而夺冠。共有5支队做出7题。难度的梯度我个人认为不是太好。AG两题过难,几乎不太可能比赛时做出来。而又有7题较常规,所以变成了D题定胜负的局面。如果能把A和G换成与D难度相当的题目,最后想必会出现激烈的争夺。

题型上,简单题的算法略显直观,综合题也都是轻易就能拆分成若干个子问题。共有两题用到二分图赋权匹配,三题用到状态空间dp。缺少了一些技巧性强的图论题和数学题不得不说是一个遗憾。算法总体来说过于常规,缺少了对创造性的考察。ADG三题可以说需要一些创造性,可惜题目太难,即使选手有想法,在final这样的比赛中也不会贸然去试。

总体上讲是一份不错的题目,不过风格上和欧洲题目有明显的不同。上交能获得冠军是他们深厚的基本功的体现,而做出D也许要仔细的分析和一些灵感。如果能把AG两题换成难度大但是有趣的图论和数学题的话,相信会使得比赛更有意思。

2005年第29届ACM ICPC世界总决赛的试题解析相关推荐

  1. 第三十届ACM/ICPC 世界总决赛题目解析

    第三十届ACM/ICPC 世界总决赛题目解析 斯坦福大学 王颖

  2. 字节跳动冬令营报名启动,邀你一起备战ICPC世界总决赛!

    面向全球顶尖高校学生举办的国际顶级训练营--2020 字节跳动 ByteCamp 冬令营,启动全球报名了! 2020 字节跳动 Byte Camp 冬令营是针对ACM程序设计竞赛(ICPC),面向全球 ...

  3. 十四届蓝桥选拔赛Scratch-2023.02.12 试题解析

    十四届蓝桥选拔赛Scratch-2023.02.12 试题解析 单选题: 1. 运行以下程序,小猫和小企鹅谁能到达舞台右侧边缘? ( B ) *选择题严禁使用程序验证,选择题不答和答错不扣分 A. 小 ...

  4. 超励志!杭电第六次打入“ACM/ICPC”全球总决赛!

    小编说: 前几天都在发 考研初试/真题 有关的内容,头条一直没有空余,所以现在才发. 杭电是计算机专业双非中最有名的学校之一,在公众号的投票[计算机最强的双非大学]中排名第一. [计算机最强的双非大学 ...

  5. 第43届ACM icpc亚洲区域赛焦作站感想

    青岛痛失银牌,焦作又是铜牌一枚,现在想想,前面三个水题,我的原因太大了,老是犯各种zz小错误,明明能秒,却花了大量时间debug,导致三个小时才签完到,最后一个小时,F题的bfs没出来,B题也没出来, ...

  6. 2021河南省第十三届ACM/icpc大学生程序设计竞赛榜单

  7. PKU ACM/ICPC竞赛队最近八年比赛成绩

    PKU ACM/ICPC竞赛队最近八年比赛成绩 (不含预选赛前十名以外) 竞赛名称 年度 获奖名次 学生姓名 备 注 第29届ACM国际 大学生程序设计竞赛 亚洲区预选赛 2004 北京赛区第4名 饶 ...

  8. 2016年第40届普吉隆ACM世界总决赛

    第40届ACM国际大学程序设计竞赛全球总决赛(ACM-ICPC World Finals)在泰国普吉隆重举行. 本届全球总决赛全世界共有128所大学(每校一队)参加,是历史上规模最大的一次,这些队伍是 ...

  9. ACM/ICPC是什么

    ACM国际大学生程序设计竞赛(英文全称:ACM International Collegiate Programming Contest(ACM-ICPC或ICPC)是由美国计算机协会(ACM)主办的 ...

最新文章

  1. 视易精通收银服务器自动关机,视易精通量贩式收银系统操作-手册3.0.doc
  2. etc的常见算法_(转)8种常见机器学习算法比较
  3. Kettle使用_29 转换里使用参数
  4. 【华为云技术分享】关于Linux下Nginx的安装及配置
  5. Linux IPC POSIX 共享内存
  6. 在window7 64位下Oracle 10g 数据库中PLSQL Developer配置和使用
  7. CCS 下载程序时报错的解决办法( TI C2000 TMS320F28379D)
  8. RTCM3.1/3.2
  9. 演化博弈与GAN网络
  10. java格式手机软件和国产mrp_国产-山寨-杂牌手机如何安装软件【MRP格式】
  11. 电路(第五版)邱关源 第一章总结
  12. Oracle Becomes 2nd Largest Software Company
  13. 报错:<ly-tab> - did you register the component correctly? For recursive components, make sure to provi
  14. vue中小写数字转换为大写数字
  15. 用Python自动批量提取Tableau报表数据源中用的数据库表
  16. 数学基础知识-排列与组合
  17. line-height的使用
  18. IE浏览器下载文本文件(txt,csv等)
  19. 四分树(UVa297紫书p160)
  20. 论MathType中空格的正确的输入方法

热门文章

  1. webview JS与nvue通讯传值
  2. ffmpeg编译安装
  3. 调查称上海IT行业本科年薪7.7万 学历高收入高
  4. vue 三元表达式动态绑定class
  5. 关于MAC安装Pycharm的总结
  6. Java - 选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)?
  7. java获取请求url地址
  8. 强大的MobaXterm xserver
  9. Python中类的基本用法
  10. 【Quarkus技术系列】「云原生架构原理」在云原生时代下的Java“拯救者”是Quarkus,那云原生是什么呢?