csp-s2021 回文
-
前言
我愈发感觉自己是个智障。
tmd这么个东西我当时是怎么做到调了几个小时的?思路出来了之后不是几分钟就能写完的吗?即使说当时脑子被驴踢了没有想到更简洁的写法,那也不至于调爆吧?那12分真的冤,代码发下来之后发现只是少了两行特判……
就这么几行代码,由于当时脑子瓦特了,硬是没搞出来,于是乎把T2也耽误了。
-
正文
看到那接近 \(10^6\) 的数据范围,可以想到要么是数据结构优化线性DP,要么是奇怪的贪心(本蒟蒻目前接触的主要就是这两种),而这道题似乎和DP扯不上什么关系,而选数之类的活动又很适合贪心,于是便往这个方向想。
由于是回文序列,那么我们的取数一定满足一个规律,最先取出的那个数,它的兄弟是最后取出来的。第二个的兄弟是倒数第二个,以此类推。
另外一个东西就是,由于只能从两头往中间取,那么一个数同时先于旁边两个数被取出来是不被允许的,道理很简单。
思考到这一步,方法就出来了啊。懒得写了,也有一部分原因是我不太想过多地提起这道伤心之题。
考场代码加四十秒的修改得到的满分代码,甚至没到2000字:
#include<cstdio>
//#define zczc
const int N=500010;
inline void read(int &wh){
wh=0;char w=getchar();int f=1;
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,pll,plr,a[N<<1];
int path[N<<1],ch[N<<1],cnt;
void solve(){
read(m);
for(int i=1;i<=m*2;i++)read(a[i]);
for(int i=1;i<=m*2;i++){
if(i!=1&&a[i]==a[1])pll=i;
if(i!=m*2&&a[i]==a[m*2])plr=i;
}
bool ok;
int l=1,r=m,sl,sr;
//left first
cnt=0,l=2,r=m*2,sl=pll-1,sr=pll+1,ok=true;
path[++cnt]=a[1];ch[cnt]=0;
for(int i=2;i<=m;i++){
if(l<sl&&a[l]==a[sl]&&l!=sl){path[++cnt]=a[l];ch[cnt]=0;l++;sl--;}
else if(l<=sl&&sr<=r&&a[l]==a[sr]&&l!=sr){path[++cnt]=a[l];ch[cnt]=0;l++;sr++;}
else if(l<=sl&&sr<=r&&a[r]==a[sl]&&r!=sl){path[++cnt]=a[r];ch[cnt]=1;r--;sl--;}
else if(sr<r&&a[r]==a[sr]&&r!=sr){path[++cnt]=a[r];ch[cnt]=1;r--;sr++;}
else{ok=false;break;}
}
if(ok){
l=1,r=m*2;
for(int i=1;i<=m;i++){if(ch[i]==0){putchar('L');l++;}else{putchar('R');r--;}}
for(int i=m;i;i--){if(a[l]==path[i]){putchar('L');l++;}else{putchar('R');r--;}}
putchar('\n');return;
}
//right first
cnt=0,l=1,r=m*2-1,sl=plr-1,sr=plr+1,ok=true;
path[++cnt]=a[m*2];ch[cnt]=1;
for(int i=2;i<=m;i++){
if(l<sl&&a[l]==a[sl]&&l!=sl){path[++cnt]=a[l];ch[cnt]=0;l++;sl--;}
else if(l<=sl&&sr<=r&&a[l]==a[sr]&&l!=sr){path[++cnt]=a[l];ch[cnt]=0;l++;sr++;}
else if(l<=sl&&sr<=r&&a[r]==a[sl]&&r!=sl){path[++cnt]=a[r];ch[cnt]=1;r--;sl--;}
else if(sr<r&&a[r]==a[sr]&&r!=sr){path[++cnt]=a[r];ch[cnt]=1;r--;sr++;}
else{ok=false;break;}
}
if(ok){
l=1,r=m*2;
for(int i=1;i<=m;i++){if(ch[i]==0){putchar('L');l++;}else{putchar('R');r--;}}
for(int i=m;i;i--){if(a[l]==path[i]){putchar('L');l++;}else{putchar('R');r--;}}
putchar('\n');return;
}
printf("-1\n");
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
int Test;
read(Test);
while(Test--)solve();
return 0;
}
一如既往,万事胜意