Loading

luogu P7915 [CSP-S 2021] 回文

题目大意

给定一个长度为 \(2n\) 的序列 \(a\),要求每次取出其第一个数或者最后一个数,使得取出的数列 \(b\) 为一个回文数列。
注:回文数列即 \(\forall i\in \{ 1,n \}\) 都有 \(b_i=b_{2n-i+1}\)

Sol

考虑第一步先取出 \(a\) 左边的那个元素,则右边同理。
如果取出左边元素,则 \(b_1=a_1\),那么 \(a\) 中与 \(a_1\) 对应的另一个元素一定最后取出,下标记为 \(p\)
可以把 \(a\) 划分成两边,即序列 \(c\) \([2,p-1]\) 和序列 \(d\) \([p+1,2n]\)
想要从其中取出元素,一定需要一个元素在这两个序列的首尾出现两次,如果有两个元素符合条件,优先选 \(c\) 中的元素(字典序最小)。
那么记当前是第 \(i\) 步,当前的操作应该存储在操作序列的 \(i\)\(2n-i+1\) 这两个位置。
(建议自己模拟一下)

接下来是分讨:

  1. \(c\) 的左右端相等,前为 L,后为 L
  2. \(c\) 的左端与 \(d\) 的左端相等,前为 L,后为 R
  3. \(c\) 的右端与 \(d\) 的右端相等,前为 R,后为 L
  4. \(d\) 的左右端相等,前为 R,后为 R
  5. 其他情况无解,请自行考虑为什么无解

Code

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1e6+10;

int n;
int a[N];
char res1[N] , res2[N];

bool calc(char res[] , int cl , int cr , int dl , int dr) {
	for(int i = 2 ; i <= n/2 ; i ++) {
		if(cl < cr && a[cl] == a[cr]) {
			res[i] = 'L'; res[n-i+1] = 'L';
			cl ++; cr --;
			continue;
		}
		if(cl <= cr && dl <= dr) {
			if(a[cl] == a[dl]) {
				res[i] = 'L'; res[n-i+1] = 'R';
				cl ++; dl ++;
				continue;
			}
			if(a[cr] == a[dr]) {
				res[i] = 'R'; res[n-i+1] = 'L';
				cr --; dr --;
				continue;
			}
		}
		if(dl < dr && a[dl] == a[dr]) {
			res[i] = 'R'; res[n-i+1] = 'R';
			dl ++; dr --;
			continue;
		}
		return false;
	}
	return true;
}

void slove() {
	cin >> n; n <<= 1;
	for(int i = 1 ; i <= n ; i ++)
		cin >> a[i];
	
	int p1 = 0 , p2 = 0;
	for(int i = 1 ; i <= n ; i ++) {
		if(i > 1 && a[i] == a[1]) p1 = i;
		if(i < n && a[i] == a[n]) p2 = i;
		if(p1 && p2) break;
	}
	
	res1[1] = 'L'; res1[n] = 'L'; res1[n+1] = '\0';
	res2[1] = 'R'; res2[n] = 'L'; res2[n+1] = '\0';
	
	if(calc(res1 , 2 , p1-1 , p1+1 , n)) cout << res1+1 << '\n';
	else if(calc(res2 , 1 , p2-1 , p2+1 , n-1)) cout << res2+1 << '\n';
	else cout << -1 << '\n';
	return;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr); cout.tie(nullptr);
	
	int T; cin >> T;
	while(T --) slove();
	return 0;
}

(比较丑陋,见谅)

posted @ 2025-10-17 20:41  lyr2023  阅读(21)  评论(0)    收藏  举报