光棍节快乐,祝天下每只single dog单身到永远;
Day1:
T1:string
现在给一个字符串,你要做的就是当这个字符串中存在两个挨着的字符是相同的时就将这两个字符消除。需要注意的是,当把这两个字符消除后,可能又产生一对新的挨着的字符是相同的。比如,初始的字符串是abcddc,dd是两个挨着的相同的字符,当把"dd"消除后,得到的字符串是abcc,这时cc又是两个挨着的相同的字符,所以又应该把cc消除。重复以上操作直到剩下的串中不存在两个挨着的字符是相同的为止,输出最终剩下的串。另需要注意的是,多对相同字符的消除顺序是不会对答案产生影响的,可以证明最后他们都会达到唯一的结果,比如,对于初始字符串adccdeed,无论是adccdeed->addeed->aeed->ad还是adccdeed->adccdd->adcc->ad,最终的输出结果都是ad。
题解:括号匹配
T2:plus
加法都会吧,恩,会这题就能看懂。
你现在有两个正整数变量X,Y,开始的时候X=Y=1。
然后刚刚那个无聊的人又出来了,他听说你既能A掉第一题又会加法就很开心,于是他又打算让你无聊一下。
无聊的人有一个正整数Z,他想让你通过两个运算得到Z,运算是这样的:
X操作:x=x+y
Y操作:y=x+y
你的目标是在最少的运算次数下,让X=Z,Y随意。
结果你一样就知道上面这题怎么写,所以无聊的人想让你再无聊一下,你需要输出运算序列(一次X操作表示为X,Y同理),并让这个运算序列的字典序最小。
20% Z<=100
50% Z=10000
100% 2<=Z<=1000000
题解:
首先要想到逆推;
如果已知最后的x,y,能否反推出前一个状态,答案是可以,若x>y,最后的一步操作一定是X,反过来一样,原因想想就能明白;
那么我们一定可以从一个x,y反推回到最初的状态去,这个过程其实就是更相减损法,减法太慢可以用除法加速;
至于字典序的问题,暴力比较就可以吧,
T3:
题意:给定一些点;
有两种问题,第一种,设f[i]表示点i与前面的点的曼哈顿距离的最大值,求∑f[i],f[1]=0;
第二种,给这个点的序列确定顺序,使第一问的答案最短;
第一问的范围在10^6,第二问范围点数不超过64,点的横纵坐标0-8;
题解:
第一问n^2算法很容易,
但数据范围太大,要解决,就必须O(1)求出f[i]的大小,这就需要一些数学变换;
f[i]=max(abs(xi-xj)+abs(yi-yj))
=max(max(xi-xj,xj-xi)+max(yi-yj,yj-yi))
=max(max(xi-xj+yi-yj,
xj-xi+yi-yj,
xi-xj+yj-yi,
xj-xi+yj-yi
))
=max(abs(xi+yi-xj+yj),abs(xi-yi-(xj-yj)))
实际上就是应用了abs(x)=max(x,-x)和max的结合律;
化成了这个式子就很明显了,设xi'=xi+yi,yi'=xi-xj,
然后只需要记录之前点的x'max,x'min,y'min,y'max即可;
我们之前为什么求不出来,是因为曼哈顿距离这东西xi,yi的信息都需要,最合适的x和最合适的y,不一定在同一个点上,因此没法求,但经过转换,我们只需要求那4个信息,所需信息量大大降低了,因此带来的时间复杂度的降低;
这让我想起来了以前我做的一道导数题目,就用到了类似这样的技巧,那道题需要我求某个带abs的函数在某区间的最大值,从而确定参数取值;
不带abs的函数在区间上单调,所以区间最值是max( abs(f(left)) , abs(f(right)) );
与今天这道题目的形式很相似,当时的解法是将abs化开,组合,最后再化成abs的形式确定最大值;
可惜比赛的时候还是没想到......
第二问:
比较神奇;
由于坐标范围较小,以及我们只需要x'min,x'max,y'min,y'max来转移的特点,以每个矩形为状态进行转移;
Day2:
T1:可持久化栈
noip出可持久化真的好吗?
题解:裸可持久化栈,当成一棵树记录状态就好;
T2:
小x在练习一门轻功,这门轻功是在梅花桩上跳来跳去,这门轻功是严格按照直线从一个梅花桩直接跳到另外一个梅花桩上。因为小x有恐高症,所以除了开始和结束的两个梅花桩,这条直线上不能有其他梅花桩,否则小x会真气中断,直接掉下来。
小x的梅花桩有W+1行,H+1列,每个梅花桩之间距离都是1米,严格按照上下左右排列,小x的轻功最少能跳L1米,最多能跳L2米。
作为一位爱思考的数学青年,小x想到了一个问题:有多少对梅花桩对小x来说是安全的,或者说有多少对梅花桩能保证小x练习这门轻功。
例如如下的地图:
W = 2 H = 1
**
**
**
而小x跳跃的长度为2和3之间。
这个梅花桩共有 (2+1) * (1+1) = 6个点以及有15 种配对方法
(0,0)-(0,1) (0,0)-(2,1) (0,1)-(2,1) (1,1)-(2,0)
(0,0)-(1,0) (0,1)-(1,0) (1,0)-(1,1) (1,1)-(2,1)
(0,0)-(1,1) (0,1)-(1,1) (1,0)-(2,0) (2,0)-(2,1)
(0,0)-(2,0) (0,1)-(2,0) (1,0)-(2,1)
在这之中,只有四种是可以满足小x跳跃长度的
始位 末位 长度 始位 末位 长度
(0,0)-(2,0) 2.00 (0,1)-(2,0) 2.24
(0,0)-(2,1) 2.24 (0,1)-(2,1) 2.00
但在这四种之中,(0,0)-(2,0)和(0,1)-(2,1)都不符合直线上没有其他梅花桩的要求,所以这个样例中只有2种结果。
题解:枚举矩形边长x,y,求gcd是否等于1,以及对角线长度是否符合要求,若是答案加上这种矩形数量;
矩形为线段是需要特判;
T3:
求将一个序列转化为不降序列的最小代价;n<=500000
题解:
有转移方程:f[i][j]=min(f[i][j-1],f[i-1][j]+abs(q[j]-a[i]))
f[i][j]递减,abs(q[j]-a[i])先减后增,可以看成两条直线的相加问题;
最后用线段树维护即可;