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;
}
posted @ 2021-11-06 19:46  Feyn618  阅读(106)  评论(0编辑  收藏  举报