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

题解:洛谷 P7915 [CSP-S 2021] 回文

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

洛谷:P7915 [CSP-S 2021] 回文 - 洛谷

【题目描述】

给定正整数n nn和整数序列a 1 , a 2 , … , a 2 n a_1, a_2, \ldots, a_{2 n}a1,a2,,a2n,在这2 n 2 n2n个数中,1 , 2 , … , n 1, 2, \ldots, n1,2,,n分别各出现恰好2 22次。现在进行2 n 2 n2n次操作,目标是创建一个长度同样为2 n 2 n2n的序列b 1 , b 2 , … , b 2 n b_1, b_2, \ldots, b_{2 n}b1,b2,,b2n,初始时b bb为空序列,每次可以进行以下两种操作之一:

  1. 将序列a aa的开头元素加到b bb的末尾,并从a aa中移除。
  2. 将序列a aa的末尾元素加到b bb的末尾,并从a aa中移除。

我们的目的是让b bb成为一个回文数列,即令其满足对所有1 ≤ i ≤ n 1 \le i \le n1in,有b i = b 2 n + 1 − i b_i = b_{2 n + 1 - i}bi=b2n+1i。请你判断该目的是否能达成,如果可以,请输出字典序最小的操作方案,具体在【输出格式】中说明。

【输入】

每个测试点包含多组测试数据。

输入的第一行,包含一个整数T TT,表示测试数据的组数。对于每组测试数据:

第一行,包含一个正整数n nn
第二行,包含2 n 2 n2n个用空格隔开的整数a 1 , a 2 , … , a 2 n a_1, a_2, \ldots, a_{2 n}a1,a2,,a2n

【输出】

对每组测试数据输出一行答案。

如果无法生成出回文数列,输出一行-1,否则输出一行一个长度为2 n 2 n2n的、由字符LR构成的字符串(不含空格),其中L表示移除开头元素的操作 1,R表示操作 2。

你需要输出所有方案对应的字符串中字典序最小的一个。

字典序的比较规则如下:长度均为2 n 2 n2n的字符串s 1 ∼ 2 n s_{1 \sim 2 n}s12nt 1 ∼ 2 n t_{1 \sim 2 n}t12n字典序小,当且仅当存在下标1 ≤ k ≤ 2 n 1 \le k \le 2 n1k2n使得对于每个1 ≤ i < k 1 \le i < k1i<ks i = t i s_i = t_isi=tis k < t k s_k < t_ksk<tk

【输入样例】

2 5 4 1 2 4 5 3 1 2 3 5 3 3 2 1 2 1 3

【输出样例】

LRRLLRRRRL -1

【算法标签】

#普及+# #贪心#

【代码详解】

// 28分#include<bits/stdc++.h>usingnamespacestd;constintN=1005;// 最大数组大小inta[N];// 原始数组,存储输入的2n个数字intb[N];// 中间数组,用于存储当前构造的序列intt,n;// t: 测试用例数量, n: 原题中的n,但数组大小是2ncharc[N];// 操作序列,记录每一步是'L'还是'R'boolflag;// 标记是否已找到合法序列// 检查当前构造的序列b是否是回文序列boolcheck(){// 从两端向中间比较for(inti=1,j=2*n;i<j;i++,j--){if(b[i]!=b[j])// 如果对应位置不相等{returnfalse;// 不是回文}}returntrue;// 是回文}// 深度优先搜索函数// left: 当前剩余数字的左边界(在数组a中的下标)// right: 当前剩余数字的右边界(在数组a中的下标)// top: 当前构造序列b的下一个位置voiddfs(intleft,intright,inttop){if(flag)// 如果已经找到合法序列,直接返回{return;}// 递归终止条件:所有数字都已使用if(left>right){// 检查当前构造的序列b是否是回文序列if(check()){// 如果找到合法序列,设置标记为trueflag=true;// 输出操作序列for(inti=1;i<=2*n;i++){cout<<c[i];}cout<<endl;}return;// 返回上一层递归}// 分支1:从剩余数字的左侧取数字b[top]=a[left];// 将a[left]放入构造序列c[top]='L';// 记录操作为'L'(从左侧取)dfs(left+1,right,top+1);// 递归处理剩余数字// 分支2:从剩余数字的右侧取数字b[top]=a[right];// 将a[right]放入构造序列c[top]='R';// 记录操作为'R'(从右侧取)dfs(left,right-1,top+1);// 递归处理剩余数字}intmain(){// 输入测试用例数量cin>>t;// 处理每个测试用例while(t--){// 输入n(但实际有2n个数字)cin>>n;// 初始化标记flag=false;// 输入2n个数字for(inti=1;i<=2*n;i++){cin>>a[i];}// 开始深度优先搜索dfs(1,2*n,1);// 如果没有找到合法序列,输出-1if(!flag){cout<<-1<<endl;}}return0;}
// 100分解法#include<bits/stdc++.h>usingnamespacestd;constintN=1000005;// 最大数组大小inta[N];// 原始数组,存储输入的2n个数字intb[N];// 构造的回文数组intc[N];// 第一组数字intd[N];// 第二组数字charans[N];// 记录操作序列,L表示从左侧取,R表示从右侧取intt,n;// t: 测试用例数量, n: 原题中的n,但实际数组大小为2nboolflag,flag2=true;// flag: 局部标记, flag2: 全局标记,表示是否找到解// 主处理函数// type: 处理类型,1表示从左侧第一个数字开始,2表示从右侧最后一个数字开始voidfunc(inttype){intx;// 关键数字,用于分割数组ints=0;// 计数器,用于跟踪关键数字的出现次数intj=0;// 数组c的指针intk=0;// 数组d的指针// 数组指针初始化intbhead=1;// 构造数组b的左指针intbtail=2*n;// 构造数组b的右指针intchead=1;// 数组c的左指针intctail;// 数组c的右指针intdhead=1;// 数组d的左指针intdtail;// 数组d的右指针// 根据type进行不同的初始分割if(type==1)// 从左侧第一个数字开始{x=a[1];// 关键数字是第一个数字for(inti=1;i<=2*n;i++){if(s<2)// 在遇到第二个x之前,放入数组c{c[++j]=a[i];}else// 遇到第二个x之后,放入数组d{d[++k]=a[i];}if(a[i]==x)// 统计关键数字出现次数{s++;}}}else// 从右侧最后一个数字开始{x=a[2*n];// 关键数字是最后一个数字for(inti=1;i<=2*n;i++){if(s<1)// 在遇到第一个x之前,放入数组c{c[++j]=a[i];}else// 遇到第一个x之后,放入数组d{d[++k]=a[i];}if(a[i]==x)// 统计关键数字出现次数{s++;}}}ctail=j;// 数组c的右边界dtail=k;// 数组d的右边界// 构造回文序列的核心循环while(bhead<btail){flag=true;// 标记本轮是否成功匹配// 情况1:数组c两端相等if(chead<ctail&&c[chead]==c[ctail]){b[bhead]=c[chead];b[btail]=c[ctail];ans[bhead]='L';// 从左侧取ans[btail]='L';// 从左侧取chead++;ctail--;bhead++;btail--;flag=false;// 成功匹配}// 情况2:数组d两端相等elseif(dhead<dtail&&d[dhead]==d[dtail]){b[bhead]=d[dhead];b[btail]=d[dtail];ans[bhead]='R';// 从右侧取ans[btail]='R';// 从右侧取dhead++;dtail--;bhead++;btail--;flag=false;// 成功匹配}// 情况3:数组c的左侧和数组d的左侧相等elseif(c[chead]==d[dhead]){b[bhead]=c[chead];b[btail]=d[dhead];ans[bhead]='L';// 从左侧取ans[btail]='R';// 从右侧取chead++;dhead++;bhead++;btail--;flag=false;// 成功匹配}// 情况4:数组c的右侧和数组d的右侧相等elseif(c[ctail]==d[dtail]){b[bhead]=c[ctail];b[btail]=d[dtail];ans[bhead]='R';// 从右侧取ans[btail]='L';// 从左侧取ctail--;dtail--;bhead++;btail--;flag=false;// 成功匹配}// 如果四种情况都不满足,说明无法构造回文if(flag){flag2=false;// 标记失败return;// 直接返回}}}intmain(){// 输入测试用例数量cin>>t;// 处理每个测试用例while(t--){cin>>n;flag2=true;// 重置成功标记// 输入2n个数字for(inti=1;i<=2*n;i++){scanf("%d",&a[i]);}// 清空数组memset(b,0,sizeof(b));memset(c,0,sizeof(c));memset(d,0,sizeof(d));// 尝试第一种分割方式(从左侧开始)func(1);if(flag2)// 如果成功{for(inti=1;i<=2*n;i++){cout<<ans[i];}cout<<endl;continue;// 处理下一个测试用例}// 清空数组memset(b,0,sizeof(b));memset(c,0,sizeof(c));memset(d,0,sizeof(d));flag2=true;// 重置标记// 尝试第二种分割方式(从右侧开始)func(2);if(flag2)// 如果成功{for(inti=1;i<=2*n;i++){cout<<ans[i];}cout<<endl;continue;// 处理下一个测试用例}// 两种方式都失败,输出-1cout<<-1<<endl;}return0;}

【运行结果】

2 5 4 1 2 4 5 3 1 2 3 5 3 3 2 1 2 1 3 LRRLLRRRRL -1
http://www.cnnetsun.cn/news/2052144.html

相关文章:

  • Qwen3-14B私有部署灾备方案:镜像备份、状态快照、跨机房容灾设计
  • 强化学习论文查找指南
  • Linux 内核参数导致连接数暴增,我用 ss + iptables 三分钟定位了 SYN Flood 元凶
  • FPGA课程设计避坑指南:搞定MIPS模型机功能测试的5个关键步骤
  • **用Python实现基于规则的音乐生成系统:从代码到旋律的奇妙之旅**在人工智能与创意产业深度融合的时代,**
  • MSYS2的C/C++,python2,python3编译环境安装脚本
  • Faster R-CNN里的RPN网络到底在干嘛?用大白话和代码图解锚框生成与训练
  • Linux文件系统(一):从磁盘结构到文件系统基础
  • 解锁学术新次元:书匠策AI——期刊论文写作的“魔法宝盒”
  • 英特尔发布至强600系列工作站处理器与锐炫Pro B70 GPU,双芯联动重塑AI工作站格局
  • DC6靶机的渗透测试与复盘
  • 终极指南:HTTrack网站镜像工具完整使用教程
  • 把远端数据当本地数据来查, 读懂 SAP HANA 里的 Federating Queries
  • FlicFlac音频转换工具:5个关键特性解析与技术实现
  • VSCode 2026工业编程配置必须做的7件事,第4件92%工程师至今忽略——否则无法通过IEC 62443安全审计
  • 从AK4490到ES9038:聊聊那些年我们用过的DAC芯片,以及它们背后的声音故事
  • 别再傻傻分不清了!Modbus RTU、TCP、RTU over TCP/IP 三兄弟到底啥区别?用Java代码实战给你讲明白
  • 西门子WinCC报表实战:手把手教你用用户归档+SQL Server实现数据查询与打印(附避坑指南)
  • 2026年转行AI产品经理,0基础小白必看!高薪风口,你准备好了吗?
  • 深度解析开源工具:如何高效实现《赛博朋克2077》存档编辑与数据修改
  • BBS短群签名方案:从q-SDH假设到可追踪匿名认证
  • Linux 进阶命令实战:sudo 授权、文件查找、文本处理与进程管理
  • Qt串口通信GUI卡顿?试试把QSerialPort丢到子线程里(附完整代码)
  • 从外网打到内网:手把手教你用MSF+Socks代理穿透CFS三层靶机网络
  • 生成引擎优化(GEO)提升数字内容互动与用户体验的新策略
  • 保姆级教程:在Ubuntu 22.04上搞定ROS2 Humble与速腾16线雷达的驱动配置
  • 策略模式的思想的经典案例分析
  • Vivado BD 地址位宽校验失败深度解析:从 [IP_Flow 19-3478] 错误到 AXI 总线对齐原则
  • Jellyfin Kodi插件终极指南:打造无缝跨设备媒体体验
  • 撕下“被动应答”的伪装:清华等团队开源 PASK,AI 终于长出了“眼力见”与“长期记忆”!