首页 > 代码库 > 1111-1112膜你赛
1111-1112膜你赛
光棍节快乐,祝天下每只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的形式确定最大值;
未完;
1111-1112膜你赛