当前位置: 首页 > news >正文

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;
}

(比较丑陋,见谅)

http://www.hskmm.com/?act=detail&tid=33249

相关文章:

  • USACO 绿-蓝 思维题小记
  • Day16-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\classlei
  • 一个实用的短视频脚本创作指令分享
  • 字典树 Trie 乱讲
  • redis和mysql之间的数据一致性
  • ubuntu允许root登录桌面系统
  • 24. 两两交换链表中的节点
  • AI协科学家:技术革命还是安全噩梦?
  • 一个决定
  • 10月17日
  • npm镜像配置
  • 一些特性
  • ubuntu安装mysql
  • 计算机视觉技术与应用深度解析
  • AGC 板刷记录1
  • 2025.10.17总结
  • 记Windows 11环境Rust下载安装配置流程
  • K8s学习笔记(九) job与cronjob - 教程
  • [HZOI]CSP-S模拟33
  • [PaperReading] VLM2Vec-V2: Advancing Multimodal Embedding for Videos, Images, and Visual Documents
  • ShandongCCPC2024
  • 标悬浮展开多级菜单
  • Nimble:让SwiftObjective-C测试变得更优雅的匹配库 - 指南
  • 2025.10.17总结 - A
  • Ubuntu创建python桌面图标
  • 深入解析Pure恶意软件家族:从RAT到构建器再到开发者
  • Ubuntu上配置Flask应用程序的Nginx和uWSGI
  • 实验一 现代c++基础课程
  • 平均融资利率求法及ORACLE语法解析
  • [Linux]如何列出被软链接的文件,列出被链接位置