老规矩,献上题目:
给定正整数 n 和整数序列 a1,a2,…,a2n,在这 2 n2n 个数中, n1,2,…,n 分别各出现恰好 2 次。现在进行 2n 次操作,目标是创建一个长度同样为 2n 的序列 b1,b2,…,b2n,初始时 b 为空序列,每次可以进行以下两种操作之一:
我们的目的是让 b 成为一个回文数列,即令其满足对所有 1≤i≤n,有 bi=b2n+1−i。请你判断该目的是否能达成,如果可以,请输出字典序最小的操作方案
每个测试点包含多组测试数据。
输入的第一行,包含一个整数 T,表示测试数据的组数。对于每组测试数据:
第一行,包含一个正整数 n。
第二行,包含 2n 个用空格隔开的整数 a1,a2,…,a2n。
对每组测试数据输出一行答案。
如果无法生成出回文数列,输出一行 ‐1
,否则输出一行一个长度为 2n 的、由字符 L
或 R
构成的字符串(不含空格),其中 L
表示移除开头元素的操作 1,R
表示操作 2。
你需要输出所有方案对应的字符串中字典序最小的一个。
字典序的比较规则如下:长度均为 2 n 的字符串 s 1∼2n 比t 1∼2n 字典序小,当且仅当存在下标1≤k≤2n 使得对于每个 1≤i 输入 #1 输出 #1 根据题意: 我们首先要明确一点:能选左边就尽量不要选右边,因为题目要求输出字典序最小的一组答案,L肯定优先于R; 其次,如果能构成b数组的话,那么输出的答案的最后一个字符一定是'L',这个不用我多说,因为选到最后只有一个字符,我们既可以把它当作左边,也可以把它当作右边。那么我们肯定要选左边啊,这样尽可能满足字典序小。 对待这道题,我们依然有2种方法: 骨灰级做法:枚举出所有可能的情况(O(2^N)),不用我说你也知道肯定要TEL掉的,我们对这种无脑方法一概而过 妙哉:我们可以内外同时开工: 最先开始,我们有两种情况——选最左边或者是最右边,我们优先选择最左边,如果左边不行再考虑右边。 我们以左边为例展开讨论(右边和左边的思路一模一样,不再累述)>>>> 给定一个长度为2n的序列N,建立数组S表示我们的答案,由’‘L’R‘组成;序列最左边记waileft,数组最右边记为wairight 初始状态下,外层waileft下标为1,wairight下标为2n 我们设最左边的数为X,取出X;然后在剩下的序列中找出与X相等的值,记作它们的下标分别为 i1,i2,记i2左边的数为neileft,i2右边的数记为neiright 取出X后,外层left下标变为i1+1,右边right不变还是2n 接下来我们就要两边同时开工了,怎么开工呢? 上述操作后,我们已经找出与X相等值的下标。由于我们最终得到的是回文序列,那么这个回文序列无论是从左到右读还是从右到左读,顺序都是一样的,容易知道,最终回文序列的两端都是X,那么回文序列临近X的一组相等的值肯定在原序列中一个在外层的最左边waileft或最右边wairight,一个在下标为i2的左边或右边(neileft or neiright)。 那好了,有四种情况: 1. N[waileft]=N[neileft] 2. N[waileft]=N[neiright] 3. N[wairight]=N[neileft] 4 N[wairight]=N[neiright] 注意:这四种情况的顺序我可不是随意写的,它必须是严谨的。为什么这么说呢? 因为上述的四种情况就是4种操作: 满足对应的情况,我们就进行相应的操作 1. L L 2. L R 3. R L 4. R R 我们还是要遵循字典序最小的原则嘛 那要是四种情况都不满足呢?那就说明这种情况不成立。我们要重新选择最右边再来,如果也不成立,那就说明这个序列不能形成回文,果断输出-1,结束程序。这是判断误解,减少冗余运算的关键一点! 这样我们判断一次就可以同时填补S数组的两端的一个值,不断向内填补空白。 如何填补? 最先开始选择左边那么S[1]=L ,S[2n]=L 如果选择右边 S[1]=R ,S[2n]=L 不管是外层还是内层,只要选择左边(waileft or neileft),我们都记作L; 只要选择右边(wairight or neiright),我们都记作R 分别由两边向内填补,这样如果能够填满,它一定是正确的答案。 完整的代码如下 程序测评结果如下: 但是我第一次提交时的代码如下: 评测结果如下: 坑了我半个多小时。读者可以比较两个代码的区别。只是多加了两行 否则有可能会把上一个结果的残余项输出出来,必须要一个结束符号!为你们敲响警钟了..... 若有不懂的地方,欢迎评论下方咨询。 写作不易,谢谢大家支持!输入输出样例
2
5
4 1 2 4 5 3 1 2 3 5
3
3 2 1 2 1 3
LRRLLRRRRL
-1
题解:
Code(100 ptx)
#include
Code(first)
#include
s[sum+1]='\0';
End~~~~