340 likes | 854 Views
IOI2009 试题讨论. 清华大学 高逸涵. 题目一览. Day 1 Archery 较难 Hiring 中等 POI 简单 Raisins 简单. Archery. 在一场射箭比赛中,比赛规则如下: 有 N 个靶位排成一排,每一轮每个靶位上两位选手进行比赛,编号小的选手一定胜出。 在 2 到 N 号靶位上的胜者移动到编号减一的靶位,负者不移动 在 1 号靶位上的胜者不移动,负者移动到 N 号靶位 初始时其他 2N-1 个选手已经排好顺序,你可以选择一个位置插队,然后按照顺序每两个选手对应一个靶位。
E N D
IOI2009试题讨论 清华大学 高逸涵
题目一览 • Day 1 • Archery 较难 • Hiring 中等 • POI 简单 • Raisins 简单
Archery • 在一场射箭比赛中,比赛规则如下: • 有N个靶位排成一排,每一轮每个靶位上两位选手进行比赛,编号小的选手一定胜出。 • 在2到N号靶位上的胜者移动到编号减一的靶位,负者不移动 • 在1号靶位上的胜者不移动,负者移动到N号靶位 • 初始时其他2N-1个选手已经排好顺序,你可以选择一个位置插队,然后按照顺序每两个选手对应一个靶位。 • 比赛一共进行R轮,你希望在R轮之后排位尽量高,在此前提下插入的位置应尽量靠后。
Archery(cont’d) • 数据规模 • 2 <= N <= 200,000 • 2N <= R <= 1000,000,000 • 60%的数据中,N不超过5,000 • 20%的数据中,N不超过200
算法讨论 请同学们踊跃发言!
算法讨论(cont’d) • 简单分析后,似乎可以发现,经过一定轮之后,选手的位置会呈现一种循环的状态。
算法讨论(cont’d) • 一旦选手们的位置进入这种状态,经过若干轮之后的位置就可以通过数学计算直接得出。 • 那么首先要解决的问题是 • 是否在有限轮之后一定能到达这种状态? • 如果是,至多经过多少轮?
算法讨论(cont’d) 定理:经过一定轮(不超过2N)之后,比赛一定会进入循环。 证明:我们只需证明在1号选手到达一号靶位之后N轮之内会进入循环即可。设2~N+1号选手为A类选手,其余为B类选手,并假设所有靶位排成一个圈,那么当A类选手和B类选手相遇时,A类选手一定向左移动。
算法讨论(cont’d) • 所以我们考虑一个B类选手,如果他在某一轮没有进行移动,我们可以认为他以后也不会再移动了。 • 假设N轮之后还有B类选手在移动,那么他一定移动了N轮,也就是说他一定经过了某一个靶位,上面没有B类选手,这就导致了矛盾。
算法一(cont’d) • 枚举插队位置,模拟2N轮比赛,直到比赛进入循环,然后计算最终位置。 • 算法复杂度:O(N^3) • 绝大多数选手第一时间想到的算法 • 只能得到20分
算法二 • 根据待插入的选手的实力,可以分为三种情况分别进行处理: • 如果待插入选手本身就是最强的,那么显然可以直接插入队尾。 • 如果实力介于2和N+1之间,那么需要找到一个合适的位置插入,使得开始循环后处于一个适当的位置使得最后结束的位置尽量靠前。 • 如果实力比N+1还要弱,那么选择一个合适的位置插入使得循环开始后的静止位置尽量靠前
算法二(cont’d) • 对于选手实力介于2和N+1之间的情况,选手会不停地循环,因此我们只需要计算出2N轮之后的哪一轮这个选手在一号靶位进行比赛即可。 • 如果我们能够快速模拟一号靶位上的比赛进行情况,那么整个问题也就迎刃而解。
算法二(cont’d) • 考虑每一轮从二号靶位晋级到一号靶位的选手: • 第一轮,是二号靶位上的胜者 • 第二轮,是上轮二号靶位上的败者和三号靶位上的胜者中的较强的一个。 • 第三轮,是……………… • 简而言之,就是在这一轮能够到达二号靶位的所有选手除去之前已经晋级的选手外的最强者
算法二(cont’d) • 可以利用堆来进行维护。 • 如果注意到对于任意两个选手,如果他们都比我们要考虑的选手强或者弱,那么他们两个之间的比赛胜负不影响最终结果。 • 因此可以将所有选手分为三类,每类选手之间没有差别。 • 可以直接维护这两类选手的个数,这样每次只需要进行常数次运算。
算法二(cont’d) • 如果选手实力比N+1号选手还要弱,那么他最终会停留在某个靶位直到比赛结束。 • 可以首先确定2N号选手的最终停留位置,然后确定2N-1号选手的最终停留位置,依次进行下去直到得到结果。
算法三 • 注意到,上述算法可以在模拟的同时计算出选手一共多少次从1号靶位移动到N号靶位的次数(设这一数字为T),结合选手的最终的位置(设这一数字为X),如果我们用X-N*T来表示模拟结果的话,我们可以认为选手每移动一次就会使结果减1。然后如果我们直观地观察模拟算法,就会发现它的结果关于初始位置是单调的,这样我们就可以利用二分检索算法解决问题。
算法三(cont’d) • 二分检索流程: • 计算从1号靶位开始的最终位置 • 计算从N号靶位开始的最终位置 • 二分查找每一个比N的倍数大的最小的最终位置 • 从上述选出的开始位置中选出一个最好的作为答案 • 容易证明总复杂度为O(NlogN)。
Hiring • 你需要从N个工人中雇佣一些工人。每个工人期望的最低工资为Sk美元,技术等级是Qk。要求雇佣的工人中支付给每个工人的工资与他的技术等级成正比,并且满足他们期望的最低工资。 • 你手上有W美元,希望能雇佣尽可能多的工人,并且总预算不超过W美元。如果有多种方案,输出所雇佣工人总工资最少的方案。
Hiring(cont’d) • 数据规模 • 50%的测试数据,N ≤ 5000。 • 所有的测试数据,1 ≤ N ≤ 500000,,1≤ Sk ≤ 20000,1≤ Qk ≤ 20000,1≤ W ≤ 10000000000。
算法讨论 每个工人只有两种属性,期望的最低工资为Sk美元,技术等级Qk。 设我们要雇佣的工人集合为K。由于题目中要求雇佣的工人的工资与技术等级成正比,我们可以将这个比值设出来,不妨设为p,那么依据题目条件,对于k∈K,有Qk×p≥Sk。 p=max{ Sk/Qk |k∈K}
算法讨论(cont’d) 将所有工人按照Sk/Qk排序,从小到大枚举p的值,然后在所有可选的工人中选取Qk最小的若干个。 注意到,如果一个工人在p较小时可以选取但没有被选取,那么他在p变大时也不会再被选取。 因此可以利用堆进行维护。
算法讨论(cont’d) 上述算法还有优化的余地,可以不使用任何高级数据结构解决问题,进而降低编程复杂度。 这个问题留给同学思考。
Raisins • 有一块N×M的巧克力,需要将其分成1×1的小块。每次可以将一块巧克力用横向或纵向的切割线分为独立的两块。每一块1×1的巧克力上都有若干葡萄干,每次切割一块巧克力需要花费的葡萄干数目与该巧克力上葡萄干的数量相等。 • 给定每块1×1的巧克力上的葡萄干数目,求总花费最少的分割方案。
Raisins 动态规划 一个子矩形可以用4个数来描述,枚举切割线的位置来进行状态转移。 时间复杂度:O(N2M2(N+M)) 空间复杂度:O(N2M2)
Decrypt Messages • 计算方程x^q=a(mod p)的所有解 • 1<=q<=10,p是质数,2<p≤1000000007
Decrypt Messages • 如果对于某个正整数a(1<a<p),a1,a2,a3,……,ap-1模p取遍1,……,p-1的所有数,则称a为p的一个原根。 • 如果我们找到了p的一个原根m,设x=my,a=mz,则原方程转化为mya=mz(mod p),又由原根的性质,上述方程等价于ya=z(mod p-1)
Decrypt Messages • 对于一般的质数,它的原根个数一般是非常之多的 • 所以我们可以逐一枚举并检验这些数是否是原根 • 一个数a是原根当且仅当a1,……,ap-2都不mod p=1 • 所以我们只需要检验ab是否mod p=1,其中b为p-1的约数
Jiajia’s Robot • 在平面上有两条线段(两条线段不退化为点,至多有一个交点),一个机器人能够射出两道互相垂直的射线,如果这两条射线分别能和这两条线段相交,则这个机器人可以定位,求平面上所有可定位的点构成区域的面积。
Jiajia’s Robot • 简单的画几个图可以猜测结论为四个圆的面积并减去四个圆的面积交。 • 证明可以从简单的情况开始讨论 • 如果其中一个线段退化成了点,情况是什么样子,然后推广到两个线段的情况。
Exciting Time • 维护一个宽度为(1<=W<=30000)的俄罗斯方块游戏,一共有N(1<=N<=30000)块掉下来,计算最后的分数以及每一列的最终高度。
Wires • 给定平面上四个点,允许添加至多3个点,使得这些点的最小生成树最小。
The Number of Sequence Pair • 给定两个序列A = {a[1], a[2], …, a[n]}, B = {b[1], b[2], …, b[n]} ,序列A,B的和为{a[1] + b[1], a[1] + b[2], …, a[2] + b[1], …, a[n] + b[n]} 一共N*N项如果这N*N项两两不同并且都在1和N*N之间,那么称这两个序列A,B是配对的。 • 给定N,求有多少个本质不同的序列对。我们认为将一个序列对整体加X,并将另一个序列整体减X得到的新序列对和原序列对是本质相同的
Mission Impossible • 给定一个有向图,某一些点有和外部连接的边,每一个节点都有至少一个入度和出度,将它分为若干块,使得每一块的所有输入边都和所有输出边之间有路径相连,并且要求答案是极小的,即不存在若干个块,把他们合并为一块之后仍旧满足题目要求。1<=N<=10000