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

abc459_d Adjacent Distinct String 的一种构造方法

原题

题目大意: 字符串 S 由小写英文字母组成,判断是否可以重排 S 使相邻字符都不同。若可以则给出一种方案。

这里我是想了一个插空构造。设按字符数从大到小排,字符依次为 \(c0, c1, c2, ...\)

首先把 \(c0\) 放进空串 \(S'\) 里,形成 \(|c0| - 1\) 个空隙。如果剩下的字符不够每一个空隙都能有一个字符插入,即 \(|c0| - 1 > |S| - |c0|\),那么显然不合法。

接下来将 \(c1\) 从左往右尽可能插入一个字符到 \(c0\) 的空隙中,如果够则在 \(S'\) 末尾插一个(类似奇偶交错)。\(|c0| \ge |c1|\),所以 \(c1\) 必然能够插完。这个时候 \(c1\) 也被隔开了。

如果 \(|c0| = |c1|\),那么刚好插完所有空隙(和末尾),那么回到 \(S'\) 开头开始下一轮,再按这种奇偶交错方法插入 \(c2\)。反之,则在之后插入 \(c2\) 直到完毕再开始下一轮。

这个时候需要考虑,假如第二种情况再回到 \(S'\) 开头后,剩余 \(c2\) 的个数足够一直插入到上一轮开始插入 \(c2\) 的位置怎么办。可以证明不会有这种情况:

上一轮开始插入 \(c2\) 的位置前有 \(|c1| \cdot 2 + 1\) 个字符,形成 \(|c1| \cdot 2\) 个可插入 \(c2\) 的空隙。这远远大于 \(|c2|\),所以不可能。

按照这种方法就可以证明不合法的充要条件是\(|c0| - 1 > |S| - |c0|\) 并给出一种构造了。其实从第二轮开始可以从 \(S'\) 开头之前开始插入,不过这样已经可以了。

#include<iostream>
#include<algorithm>
using namespace std;
int T;
struct node {int cnt,let;
}
ch[26];
bool cmp(node x, node y) {return x.cnt > y.cnt;
}
int main() {cin >> T;while (T--) {string s;cin >> s;for (int i = 0; i < 26; i++) ch[i] = {0,'a' + i};for (char i: s) ch[i - 'a'].cnt++;sort(ch, ch + 26, cmp);if (ch[0].cnt - 1 > s.size() - ch[0].cnt) { // 判断是否合法cout << "No" << endl;continue;}cout << "Yes" << endl;int tot = -1;for (int i = 25; i >= 0; i--) // 统计出现字符种类数if (ch[i].cnt) {tot = i;break;}string ans = "";ans.append(ch[0].cnt, ch[0].let); // 先放入 c0ch[0].cnt = 0;bool stop = 0;int flag = 1; // 标记当前还有剩余的最多的一种字符while (!stop) {string tmp = ""; // 直接模拟插入不太好写,故维护插入空隙的字符所形成的子序列while (tmp.size() < ans.size()) { // 最多插入原串长度个字符,不然插不下if (ch[flag].cnt == 0) flag++; // 用完就换下一种字符插入if (flag > tot) { // 没有字符了,停止插入stop = 1;break;}if (tmp.size() + ch[flag].cnt <= ans.size()) { // 可以在这一轮把 ch[flag] 插完tmp.append(ch[flag].cnt, ch[flag].let);ch[flag].cnt = 0;} else { // 否则ch[flag].cnt -= ans.size() - tmp.size(); // 注意这一句要先写,不然 tmp.size() 会变tmp.append(ans.size() - tmp.size(), ch[flag].let);}}string ttmp = "";for (int i = 0; i < tmp.size(); i++) ttmp += ans[i], ttmp += tmp[i]; // 形成一轮插入后的字符串ttmp.append(ans.substr(tmp.size())); // 如果中途没有字符,tmp.size()会小一些,故把原串剩下的直接接到后面。// 显然这一句只可能在最后一轮执行。由合法条件易得假如第二轮执行这一句,// 原串最多只会剩一个字符,故没有问题。ans = ttmp;}cout << ans << endl;}return 0;
}
http://www.jsqmd.com/news/876485/

相关文章:

  • 11全排列 回溯
  • Postman 401错误排查:Bearer Token认证填法与工程化实践
  • 抖音批量下载器终极指南:如何3分钟搞定无损音乐提取与高效素材管理
  • 30+平台一键文档下载:告别繁琐流程,实现“所见即所得“的自由
  • 2026年免费降AI/AIGC率保姆级教程:3款亲测好用不踩雷的降AI工具 - 降AI实验室
  • 如果你要设计一个“个人助理“Agent,记忆系统应该如何分层?
  • 如何快速配置Atmosphere破解系统:Switch游戏体验全面升级指南
  • 微信小程序逆向:基于Frida Hook WeChatAppHost.dll解密wxapkg
  • SHAP值在时间感知研究中的应用:从机器学习预测到认知机制解释
  • 终极解决方案:如何彻底解决Reloaded-II模组加载器的依赖循环与下载死锁问题
  • 超参数调优中的评估偏差:数据泄露如何导致模型性能误判
  • 火眼取证+雷电模拟器深度联调实战指南
  • 宜春2026最新黄金回收本地口碑商家榜:黄金首饰+白银+铂金+彩金回收门店及联系方式推荐 - 前途无量YY
  • 终极Windows进程内存操控指南:Xenos DLL注入器深度实战解析
  • runc符号链接挂载漏洞导致容器逃逸的原理与实战防护
  • 基于MultiFold无分箱反卷积的轻子-喷注方位角不对称性测量
  • Reloaded-II 模组加载器:深入解析依赖管理机制与循环依赖解决方案
  • MIT-BIH-AF数据集处理避坑指南:wfdb库使用、信号对齐与常见错误解决
  • SHAP可解释性分析在医疗AI决策中的应用:以肾脏移植预测为例
  • CTF MISC终极武器:如何用PuzzleSolver快速破解各类隐写与编码挑战
  • 微信聊天记录永久保存终极指南:用WeChatExporter告别数据焦虑
  • 终极资源嗅探指南:猫抓浏览器扩展帮你轻松捕获网页媒体资源
  • 别再死记硬背MFCC公式了!用Python手把手带你复现FBank/MFCC特征提取全流程
  • Cursor内置浏览器遭恶意MCP服务器劫持:信任链攻防实战
  • Android Native逆向实战:Frida与IDA协同分析ART内存模型
  • QMC音频解密神器:qmc-decoder帮你轻松解锁加密音乐文件
  • 5分钟制作专业LRC歌词:零基础快速上手指南
  • Steam创意工坊下载终极指南:WorkshopDL跨平台模组自由教程
  • 抖音下载器完整指南:3分钟批量下载无水印视频和音乐
  • 从留存率23%到76%:Lovable开发实践全链路,含可复用的8个情感化交互组件