油滴扩展

【问题描述】

在一个长方形框子里,最多有 N(0≤N≤6)个相异的点。在其中任何~个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这 N 个点上放置油滴,才能使放置完毕后所有油滴占据的总面积最大呢?(不同的油滴不会相互融合)

注:圆的面积公式 V=pi*r*r,其中 r 为圆的半径。

【解题过程】

直接搜索。注意点是:如果一个点在扩展之前已经被一个较大的圆覆盖了,那么在这个点即使扩展也只能扩展到内切为止,对结果没有影响,所以可以不用考虑。

初始得分 100 分。

 

数列

2. 数列 (sequence.pas/c/cpp )

【问题描述】

虽然 msh 长大了,但她还是很喜欢找点游戏自娱自乐。有一天,她在纸上写了一串数字:1,1,2,5,4。接着她擦掉了一个 1,结果发现剩下 1,2,4 都在自己所在的位置上,即 1 在第 1 位,2在第 2 位,4 在第 4 位。她希望擦掉某些数后,剩下的数列中在自己位置上的数尽量多。她发现这个游戏很好玩,于是开始乐此不疲地玩起来……不过她不能确定最多能有多少个数在自己的位置上,所以找到你,请你帮忙计算一下!

【输入】

第一行为一个数 n,表示数列的长度。接下来一行为 n 个用空格隔开的正整数,第 i 行表示数 Ai。

【输出】

一行一个整数,表示擦掉某些数后,最后剩下的数列中最多能有多少个数在自己的位置上,即 Ai=i最多能有多少。

【解题过程】

马上想到对每个数字与位置作差,比如

数列:1 1 2 5 4

位置:1 2 3 4 5

作差:0 1 1 -1 1

从中可以看出,差为负数的数字不用考虑(不管怎么删都不可能到达正确的位置)。

可以发现,我们每在一个位置删去一个数,后面的差值就会减 1。显然,我们最终的答案中的序列中每个数的初始差值排在一起一定是一个最长非降子序列。所以我们只要在差值序列里找最长非降子序列即可。但是这个序列有一定的限制。比如如果要在 1 后面接 3,那么在这两个之间必然要有 2 个元素被删去,所以它们的位置之差应该大于值的差。

以上面的数据为例,

位置 3 的元素 2 如果想要接到位置 1 的元素 1 的后面,中间必然要删去一个数,位置之差 = 3-1,值之差 = 1-0,满足条件,所以可以接上。而位置 2 的元素 1 很明显不能接到位置 1 的元素 1 后面。

但就是因为这个地方导致我不敢写简单明了的动态规划,而是选择了不靠谱的贪心(这什么心态)。初始得分 20 分。

 

黑匣子

【问题描述】

Black Box 是一种原始的数据库。它可以储存一个整数数组,还有一个特别的变量 i。最开始的时候 Black Box 是空的.而 i 等于 0。这个 Black Box 要处理一串命令。

命令只有两种:

ADD(x):把 x 元素放进 Black Box;

GET:i 加 l,然后输出 Black Box 中第 i 小的数。记住:第 i 小的数,就是 Black Box 里的数的按从小到大的顺序排序后的第 i 个元素。例如:

我们来演示一下一个有 11 个命令的命令串。(如下图所示)

现在要求找出对于给定的命令串的最好的处理方法。ADD 和 GET 命令分别最多 200000 个。现在用两个整数数组来表示命令串:

1.A(1),A(2),…A(M):一串将要被放进 Black Box 的元素。每个数都是绝对值不超过2000000000 的整数,M≤200000。

例如上面的例子就是 A=(3,1,一 4,2,8,-1000,2)。

2.u(1),u(2),…u(N):表示第 u(j)个元素被放进了 Blaek Box 里后就出现一个 GET 命令。

例如上面的例子中 u=(l,2,6,6)。输入数据不用判错。

【输入】

第一行,两个整数,M,N。

第二行,M 个整数,表示 A(l)……A(M)。

第三行,N 个整数,表示 u(l)…u(N)。

【输出】

输出 Black Box 根据命令串所得出的输出串,一个数字一行。

【解题过程】

就是动态查询第 k 大的问题。

Treap 什么的早就忘掉了。本来打算直接写个裸的 BST 水个五六十分的,后来想想还是不靠谱。没想到标程就是裸 BST,而且时间完虐其他任何方法。这数据应该说还是太温和了,如果是我出题的话怎么的也要把 BST 卡在 60 分以下吧。

然后考虑用线段树。用 sum 域维护区间内有几个数,每次根据左子树的 sum 与 k 的大小关系来向左或右递归直到找到叶子节点。

但是题目给出的数值的范围是 [-2000000000, 2000000000],如果直接写很明显不实际。但是只有 200000 个数字。这种情况下主要有两种处理方法:

  1. 动态开辟结点(用到结点时再开辟,但不是用 new,而是用事先定义好的数组中的元素来替代)
  2. 离散化

我用的是离散化。200000 个数字排个序,那么每个数字都可以与它自己的位置一一对应,数字的大小关系和位置的大小关系是对应的。所以往线段树中插入的不再是数字本身,而是其位置编号。

但是如何知道每个数字的位置编号呢?我用了一个 hash 表,将数值散列到对应的位置编号(用开链法解决冲突)。但事实上这种方法是很低效的,大多数时间浪费在了 hash 上。更好的做法是,将数值在原序列中的位置编号散列到对应的排序后的位置编号。这样就是一一对应的关系了,hash 的复杂度成了真正的 O(1)。

初始得分 20 分。(8 个点超时)原因一是刚才提到的 hash 方法不合理,原因二是线段树的插入写错导致大量的无用递归。

02day2的更多相关文章

随机推荐

  1. C++文件操作之 seekg/seekp/tellg/tellp

    问题描述: C++文件操作之 tellg/tellp/seekg/seekp 的使用 问题解决: (1)seekg/tellg/seekp/tellp 使用 tellp用于ostream调用,用来&q ...

  2. ios开发之网络访问的数据类型

    1> JSON 特点:1. [ ] 表示数组  {} 表示字典 - 对象模型建立关系 2. 应用非常多,基本上移动开发的主要数据传输都是JSON 要使用JSON,从网络上获取到数据data后,直 ...

  3. [设计模式] 7 适配器模式 adapter

    在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用 类模 ...

  4. PE文件结构详解(一)基本概念

    PE(Portable Execute) 文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任 何扩展名.那 ...

  5. ssh 内在溢出

    相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的认识. 在解决j ...

  6. DIY Ruby CPU 分析——Part I

    [编者按]原文作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是DIY Ruby CPU Profiling 的第 ...

  7. LightOj 1096 - nth Term (矩阵快速幂,简单)

    题目 这道题是很简单的矩阵快速幂,可惜,在队内比赛时我不知什么时候抽风把模版中二分时判断的 ==1改成了==0 ,明明觉得自己想得没错,却一直过不了案例,唉,苦逼的比赛状态真让人抓狂!!! #incl ...

  8. POJ 2106 Boolean Expressions (布尔表达式求值)

    题意:关于!,&,| 的运算,表达式中V代表true,F代表false. 思路:见代码吧,很详细了. 要注意 !!!F,!(...) 的情况. #include <iostream> ...

  9. hdu 1133 Buy the Ticket

    首先,记50的为0,100的为1. 当m=4,n=3时,其中的非法序列有0110010; 从不合法的1后面开始,0->1,1->0,得到序列式0111101 也就是说,非法序列变为了n-1 ...

  10. Oracle的学习二:表管理(数据类型、创建/修改表、添加/修改/删除数据、数据查询)

    1.Oracle表的管理 表名和列名的命名规则: 必须以字母开头: 长度不能超过30个字符: 不能使用oracle的保留字: 只能使用如下字符:A-Z, a-z, 0-9, $, # 等. Oracl ...