油滴扩展

【问题描述】

在一个长方形框子里,最多有 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. 【BZOJ】【1272】【BeiJingWC2008】Gate of Babylon

    组合数学+容斥原理 Orz zyf-zyf 多重集组合数0.0还带个数限制?  ——>  <组合数学>第6章  6.2带重复的组合 组合数还要模P 0.0? ——> Lucas ...

  2. texCUBE() to CubemapSampler.Sample()

    update dx9 to dx11 refers to   CUBEMAP sampler texCUBE(CubeMpaSampler,normal) maybe change to Cubema ...

  3. phonegap 环境搭建

    经过了一番讨论,最后还是决定用phonegap来开发产品.因为用phonegap的人力成本相比原生开发还是节省了不少,并且可以跨平台.至于软件的运行效率,在ios上还是相当流畅的,在android上就 ...

  4. mySql 的基本操作

    mysql -uroot -proot show databases; use ltcl_net;show tables; desc tablename; 查看表结构 create table tes ...

  5. Android开发--使用真机进行USB调试程序

    在android小程序的开发过程中,使用eclipse中的虚拟机进行程序开发速度较慢,用真机开发可以显著提高调试的速度. 这里我用的操作系统是win7专业版,手机型号HM1S: 进行USB调试的主要步 ...

  6. C Primer Plus 第3章 数据和C 编程练习

    1. /* 整数上溢 */ #include <stdio.h> int main(void) { ; unsigned ; /* 无符号整数j像一个汽车里程指示表(形容的太好了,可参考& ...

  7. 解决 Ubuntu 开机 Waiting for 60 seconds more for network configuration

    sudo vim /etc/network/interfaces, 将该文件的内容修改为如下:(也就是说删掉其他的什么auto eth0.auto wlan0) auto lo iface lo in ...

  8. 套题T3

    秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  9. cojs 简单的01串 题解报告

    题意显然是求n位二进制串中不大于其逆序串,取反串,逆序取反串的所有串按字典序排序后的第k个 由于n很小,k很大所以我们可以考虑逐位确定 问题转化为了求方案数,这显然是可以用数位DP做的 设f[len] ...

  10. eclipse中(装了插件m2eclipse后的)导入maven工程显示"感叹号"

      有时候导入一些开源工程(maven结构的),在eclipse中(装了插件m2eclipse后的)该工程前面会有一个小的红色感叹号,但点开工程后没有发现有打小红叉的内容,这种情况其实大部分是jar包 ...