链接:

P7915


题意:

给出一个长度为 \(2n\) 的序列 \(a\),其中 \(1\sim n\) 每个数出现了 2 次。有 L,R 两种操作分别是将 \(a\) 的开头或末尾元素加入到初始为空的序列 \(b\) 里,目标是让 \(b\) 成为一个回文串。

需要判断无解或求出字典序最小的方案。

\(T(T\leq100)\) 组数据,对于每组数据 \(n\leq5\times10^5\)。\(\sum n\leq5\times10^5\)。


分析:

首先对于 \(a\) 串,一定存在一个分界点使得左边的元素是通过 L 操作弹出的,右边的元素是通过 R 操作弹出的,显然 \(b\) 的末尾就在这个分界点的两边,显然 \(b\) 的末尾一定是 \(a\) 的开头或结尾,这里先假设是开头。

那么找到这个分界点,也就是与 \(a_1\) 相同的位置。发现序列被分成了两段,左边一段是从左往右通过 L 操作弹出的,右边一段是从右往左通过 R 操作弹出的,那么我们把这两段拉出来,这里有个细节就是分界点要分在左边一段,因为要求字典序最小。

假设与 \(a_1\) 相等的地方是 \(i\),\(i\) 的下一个位置是 \(j\),大概就是:

变成了两个队列,队首在 \(b\) 的前面,队尾在 \(b\) 的后面,那么只要队首和队尾能配对,就贪心选择字典序小的并加入到 \(b\) 里就可以了。

然后如果 \(b\) 的末尾是 \(a\) 的末尾,就重新找分界点再做一遍就行了。

另外,可能会存在 \(a\) 的开头等于 \(a\) 的末尾的情况,此时除非原始串就是回文串,否则是无解的,特判一下就行了。


算法:

找到分界点,维护两个双端队列,贪心选择即可。


代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int N=5e5+5;
int T,n,a[N<<1];
int flag,s,e;
int A[N<<1],ai,an;
int B[N<<1],bi,bn;
int ans[N<<1];
signed main(){
freopen("palin.in","r",stdin);
freopen("palin.out","w",stdout);
T=in;
while(T--){
flag=1;n=in;
for(int i=1;i<=(n<<1);i++)a[i]=in;
for(int i=1;i<=n;i++)
if(a[i]!=a[(n<<1)-i+1])flag=0;
for(int i=2;i<(n<<1);i++){
if(a[i]==a[1])s=i;
if(a[i]==a[(n<<1)])e=i;
}
if(a[1]==a[(n<<1)]){
if(flag){for(int i=1;i<=(n<<1);i++)putchar('L');puts("");}
else puts("-1");
continue;
}
for(int i=1;i<=s;i++)A[i]=a[i];an=s;bn=(n<<1)-s;
for(int i=(n<<1);i>=s+1;i--)B[(n<<1)-i+1]=a[i];
ai=1,bi=1,flag=0;
for(int i=1;i<=n;i++){
if(ai<an&&A[ai]==A[an])
ans[i]=ans[(n<<1)-i+1]='L',ai++,an--;
else if(ai<=an&&bi<=bn&&A[ai]==B[bn])
ans[i]='L',ans[(n<<1)-i+1]='R',ai++,bn--;
else if(bi<bn&&B[bi]==B[bn])
ans[i]=ans[(n<<1)-i+1]='R',bi++,bn--;
else if(ai<=an&&bi<=bn&&B[bi]==A[an])
ans[i]='R',ans[(n<<1)-i+1]='L',bi++,an--;
else flag=1;
}
if(!flag){
for(int i=1;i<=(n<<1);i++)
cout<<(char)ans[i];
puts("");
}
else{
s=e;
for(int i=1;i<=s;i++)A[i]=a[i];an=s;bn=(n<<1)-s;
for(int i=(n<<1);i>=s+1;i--)B[(n<<1)-i+1]=a[i];
ai=1,bi=1,flag=0;
for(int i=1;i<=n;i++){
if(ai<an&&A[ai]==A[an])
ans[i]=ans[(n<<1)-i+1]='L',ai++,an--;
else if(ai<=an&&bi<=bn&&A[ai]==B[bn])
ans[i]='L',ans[(n<<1)-i+1]='R',ai++,bn--;
else if(bi<bn&&B[bi]==B[bn])
ans[i]=ans[(n<<1)-i+1]='R',bi++,bn--;
else if(ai<=an&&bi<=bn&&B[bi]==A[an])
ans[i]='R',ans[(n<<1)-i+1]='L',bi++,an--;
else flag=1;
}
if(!flag){
for(int i=1;i<=(n<<1);i++)
cout<<(char)ans[i];
puts("");
}
else puts("-1");
}
}
return 0;
}

题外话:

没想到会这么简单,失策了

[CSP-S2021] 回文的更多相关文章

  1. LeetCode[5] 最长的回文子串

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  2. 最长回文子串-LeetCode 5 Longest Palindromic Substring

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  3. [LeetCode] Longest Palindrome 最长回文串

    Given a string which consists of lowercase or uppercase letters, find the length of the longest pali ...

  4. [LeetCode] Palindrome Pairs 回文对

    Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that t ...

  5. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  6. [LeetCode] Palindrome Permutation 回文全排列

    Given a string, determine if a permutation of the string could form a palindrome. For example," ...

  7. [LeetCode] Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  8. [LeetCode] Shortest Palindrome 最短回文串

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...

  9. [LeetCode] Palindrome Partitioning II 拆分回文串之二

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  10. [LeetCode] Palindrome Partitioning 拆分回文串

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

随机推荐

  1. servlet请求转发于重定向

    请求的转发与重定向是Servlet控制页面跳转的主要方法,在Web应用中使用非常广泛. 一. 请求的转发 Servlet接收到浏览器端请求后,进行一定的处理,先不进行响应,而是在服务器端内部" ...

  2. Java基础系列(9)- 数据类型扩展及常见面试题

    整数拓展 // 整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x // 同一个数字在不同进制中,结果是不同的,进制换算 int i = 10; int i2 = 010; // 八进制 i ...

  3. python学习笔记(三)-列表&字典

    列表: 一.列表操作"""Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素.比如,列出班里所有同学的名字,就可以用一 ...

  4. django错误处理

    1.django.db.utils.OperationalError: no such table 意思:没有这个app应用对应的数据表的,可以用 python manage.py makemigra ...

  5. 获取用户id的方法

    /** 获取ip */function getip() { if(getenv("HTTP_X_FORWARDED_FOR")!=''){ $cip = getenv(" ...

  6. c++ 的学习 第3集-默认参数

    1.默认参数的意思就是  予以形参默认值 2. C++允许函数设置默认参数,在调用时可以根据情况省略实参.规则如下: 默认参数只能按照右到左的顺序 如果函数同时有声明.实现,默认参数只能放在函数声 ...

  7. P2179-[NOI2012]骑行川藏【导数,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/P2179 题目大意 给出\(E\)和\(n\)个\(s_i,k_i,u_i\)求一个序列\(v_i\)满足 \[\s ...

  8. IE浏览器设置兼容性

    因为IE浏览器不兼容高版本的Jquery.Bootstrap等JS框架,导致页面在Google浏览器和在IE的显示完全不一样,所以需要对页面进行兼容性设置 <!--设置兼容性--> < ...

  9. mysql的一次意外

    打开navcat连接本地mysql数据库的时候说mysql服务无法连接,切换到cmd用命令行来启动报错,发生系统错误5,查看百度,需用管理员权限运行, 用管理员运行依旧不好使 C:\WINDOWS\s ...

  10. Python 通过 .cube LUT 文件对图像加滤镜

    Python 通过 .cube LUT 文件对图像加滤镜 一个好用的python给图片加滤镜的代码: https://github.com/CKboss/PyApplyLUT 这个是对C++代码的封装 ...