您的位置:首页 > 其它

魔法训练

2015-09-04 08:49 309 查看
前言:由于太无聊,所以开坑,目标是叉姐的魔法训练。ps:hust上 dafashi

初级魔法训练

传送门

1. p1:

题意:给定n个集合,每个集合内有一些数字(可以重复)。给出q个询问,每次给出两个数x,y,问能否有一个集合同时包含x,y两个数。(n<=1000,q<=20w)

solution:trie树上应用bitset

2. p2:

题意:有n个三元组(x,y,z)(x,y,z),定义两个三元组之间的差为D=max(x1−x2,y1−y2,z1−z2)−min(x1−x2,y1−y2,z1−z2)D=max(x1-x2,y1-y2,z1-z2)-min(x1-x2,y1-y2,z1-z2),求所有pair的差之和。(n<=20w)(n<=20w)

solution:设x=x1−x2,y=y1−y2,z=z1−z2x=x1-x2,y=y1-y2,z=z1-z2. 那么D=max(x,y,z)−min(x,y,z)D=max(x,y,z)-min(x,y,z),在数轴上画出这三个点,可以发现D=(|x−y|+|x−z|+|y−z|)/2D=(|x-y|+|x-z|+|y-z|)/2,再将绝对值里面的数打开,发现有规律,然后就OK了。

闪光点:将max−minmax-min转换一下(只适应3个点)

3. p3:

只要观察到每列都是单调的就OK了

冰系魔法入门

传送门

p1

题意:给定3个矩阵(a,b,c)(a,b,c),c=a∗bc=a*b,但是cc里有可能有一个元素是错误的,要求找到这个元素。矩阵的维度<=1000<=1000

solution:显然O(n3)O(n^3)的矩阵乘法是不行的。首先判断错误元素出现在哪一行,这个可以O(n2)O(n^2)解决(将矩阵bb每行元素结合成一个),然后再O(n2)O(n^2)判断是哪一列出现错误。

闪光点:特殊情景特殊考虑,创造性的将矩阵bb合并成11列。

p2

题意:勇士战恶龙,有nn回合,每一回合勇士有以下动作可供选择

attack:对恶龙造成xx点伤害

defend:在这一回合无视恶龙的攻击

heal:回复自己y点血量

恶龙则是在回合ii对勇士造成a[i]a[i]的伤害

勇士初始血量:hp1hp1 恶龙初始血量:hp2hp2

谁的血量<=0<=0谁死亡,找到最优策略

闪光点:时光倒流。

solution:假设我每次都攻击,如果当前回合要死了,我就取消前面某一回合的攻击,顺便回血。所以维护一个
max(a[i],y)
的优先队列。

p3

计算几何,待搞懂。

收获:优先队列贪心实现的时光倒流,类似的还有汽车加油问题,

火球术入门

传送门

p1

题意:FJ有nn种硬币,面值为a[i]a[i]的硬币数量有b[i]b[i]个,现在他要给员工发工资,每个月至少XX元,只能多不能少,现在他想知道最多能给员工发多少月的工资。

solution:先用面值大的硬币凑成恰好少于XX的面值,然后再用小的补上来。

p2

题意:在一个二维区域,有一片连在一起的森林,其他地方全是草地(可以行走),主人公现在正在其中某一个草地上,现在他想从初始位置出发,围着森林绕一圈(也就是说路径包围森林),然后回到初始位置,问最短的路程。

solution:应用既然要包围,那么从森林的某一点向右边界连一条线,可以知道路径一定是经过这条线的,所以枚举这条线上的点,开始从
非上
非下
bfs,两个加起来构成了一个围着森林的闭合路径。具体实现:bfs的时候特判当前点是否在上述直线上,如果在那么限制方向,否则的随意。

闪光点:特殊的bfs,实在妙

风系魔法基本要领

传送门

p1:

由于没有什么特别的闪光点,所以不写题解了。

p2:

题意:经典的在河两岸修建桥的问题,只不过这次,某一岸的城市是10w数量级,另一个是2K数量级。

solution:首先O(n∗m)O(n*m)数量级的
dp
方程很容易写出,dp[i][j]=min(dp[i−1][j],dp[i−1][j−1]+abs(x[i]−y[j]))dp[i][j]=min(dp[i-1][j],dp[i-1][j-1]+abs(x[i]-y[j])),然后优化一下,把mm优化成2∗n2*n,也就是对电脑来说,在服务器位置前nn个和后nn个。然后复杂度就是O(n2)O(n^2)了.

p3:

题意:一个长度为n的序列,给出询问[L,R],我们要找到最长连续子序列使得这个子序列里面的元素全都不相同。

solution:首先一个
dp
预处理出所有元素向左延伸的最大范围,也就是在这个范围里没有重复元素。然后查询[L,R]的时候,如果能延伸的最左端
>=L
的时候,可以直接RMQ查询,唯一麻烦的就是最左端
<L
的情况,但是观察一下,
dp
数组是单调的,所以我们可以二分找到
>=L
的下标,分两种情况讨论。

闪光点:单调和RMQ的巧妙结合。

我是如何成为一名合格的小学生的?

传送门

p1:

题意:有n个元素,每个元素可以属于集合A,也可以属于集合B,当属于集合A的时候,他的值是
a[i]
,当属于集合B的时候,他的值是
b[i]
,找到一种划分方案使得max(A)+max(B)max(A)+max(B)最小。

solution:先将n个元素按a的值大小排序,然后枚举n次,注意预处理处从后往前b值得最大值。因为我枚举第一维的时候,因为左端的a值都小于当前的a值,所以如果左端取得话,对A的最大值没有影响,但是如果不取的话,有可能增加B的最大值,所以我默认全部都取。

p2:

题意:有一个4∗n4*n的板,现在要将他的每一格涂某些颜色,对于格子(x,y)(x,y),其颜色为Ax,yA_{x,y},那么必须满足Ax,y>=Ax,y−1A_{x,y} >=A_{x,y-1} ,也就是同一行,后一格颜色大于等于前一格。除此之外,还会给出一些限制条件,Ax1,y1==Ax2,y2A_{x_1,y_1} ==A_{x_2,y_2} 。

solution:首先观察1∗n1*n的板,我们用
dp[i][j]
表示第i个格子用颜色j所能产生的方案数。dp[i][j]=∑jk=1dp[i−1][k]dp[i][j]=\sum_{k=1}^j{dp[i-1][k]},我们将这个方程转换一下(用另一种形式表示),我们将dp的第二维消掉

for(int i=0;i<=255;i++)//遍历颜色
{
    for(int j=0;j<=n;j++)
    {
        if(j+1>n)
            continue;
        dp[j+1]+=dp[j];//dp[j]表示格子j的颜色<=i的方案数
    }
}


如果这样表示dp方程的话,同样可以适用于4维的,用
dp[i][j][k][w]
表示小于等于当前颜色的所有方案,注意,有点像扫描线。需要预处理出所有不能放的位置,也就是题目中的限制条件。似乎说不清.代码.

暴雨术入门

传送门

p2

题意:给你一些面值,每种面值只能用一次,问最小的不能组合出来的面额(正整数)。

solution:咋一看有点像博弈里面的
mex
,但是题目给的范围并不能用
dp
搞出来。我们将面值排下序,假如我们当前已经可以拼出[1,limit][1,limit]范围的所有数值,假如当前处理的面值为xx,假如x>limit+1x>limit+1,那么limit+1limit+1永远也不可能被拼出来,否则的话更新limit=limit+xlimit=limit+x。

p3

题意:有一个数列AA,初始都是00,每次进行以下操作,(L,R,c)(L,R,c),表示对于区间[L,R][L,R]里每个数,如果小于PP,那么A[i]+=cA[i]+=c,否则的话,A[i]+=2∗cA[i]+=2*c.

solution:这个题网上流传一种线段树的写法,估计是以前数据太水了,现在加强数据了,只要是用线段树写的都过不了。正解是用树状数组维护时间,对于操作(L,R,c)(L,R,c),在LL处添加一个事件(c,time)(c,time)表示在timetime时间加个cc,在R+1R+1处添加一个事件(−c,time)(-c,time)表示在timetime时间减个cc,然后ii从11到nn遍历,首先把所有事件处理完,然后二分时间,找到最小的时间,使得在这个时间之前加的数已经使得A[i]A[i]大于等于PP,找到这个就好办了,剩下的时间乘以两倍就可以了。

实在妙
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: