P7915 [CSP-S 2021] 回文
题传
很有意思的一道题,不过我考场上一直刚 T2 导致压根没时间看()。
这题拿到看起来很离谱的样子,先考虑怎么暴力吧。
最朴素的暴力显然就是
思考:我们每次都是搜完所有方案再去判断是否正确,这十分耗时,能否用一种方法,边搜边判呢?
继续往下思考:我们怎么判断这是一个解,肯定是拿个指针从两边向中间扫,如果有不匹配的就返回非解,那么搜索的时候能不能也像这样做呢?
我们珂以枚举
考虑对其再来一个贪心,显然优先级为 LL --> LR --> RL --> RR,只要有一个可行我们就只搜这一条路,那么复杂度为
然后你就发现这其实跟 T1 一样是个猜了结论就会做的题。。。
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mo=1e9+7;
inline int read(){
char ch=getchar();int x=0, f=1;
while(!isdigit(ch)) f=(ch=='-'?-1:f), ch=getchar();
while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0', ch=getchar();
return x*f;
}
const int N=5e5+5;
int n, L[N], R[N], a[2*N], b[2*N];
char ans[2*N];
bool doit(int lst, int Li, int Ri){
if(Li==2) ans[1]='L';
else ans[1]='R';
int l=lst, r=lst, st=2, ed=2*n-1;
for(int i=1; i<n; i++){
if(R[a[Li]]==l-1) l--, Li++, ans[st++]='L', ans[ed--]='L';
else if(R[a[Li]]==r+1) r++, Li++, ans[st++]='L', ans[ed--]='R';
else if(L[a[Ri]]==l-1) l--, Ri--, ans[st++]='R', ans[ed--]='L';
else if(L[a[Ri]]==r+1) r++, Ri--, ans[st++]='R', ans[ed--]='R';
else return 0;
}
ans[2*n]='L';printf("%s\n", ans+1);return 1;
}
void solve(){
memset(L, 0, sizeof(L));
memset(R, 0, sizeof(R));
memset(b, 0, sizeof(0));
memset(ans, 0, sizeof(ans));
n=read();for(int i=1; i<=2*n; i++)
a[i]=read(), L[a[i]]?R[a[i]]=i:L[a[i]]=i;
if(doit(R[a[1]], 2, 2*n)) return ;
if(doit(L[a[2*n]], 1, 2*n-1)) return ;
puts("-1");return ;
}
signed main(){
int T=read();while(T--) solve();
return 0;
}