当前位置: 首页 > 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.gsyq.cn/news/1365764.html

相关文章:

  • DLSS Swapper终极教程:5分钟掌握免费游戏性能优化神器
  • 超参数调优中的评估偏差:数据泄露如何导致模型性能误判
  • 2026年免费降AI/AIGC率保姆级教程:3款亲测好用不踩雷的降AI工具 - 降AI实验室
  • 保姆级教程:在CentOS 7/8上从源码编译安装最新版ProxyChains-ng(含systemd服务配置)
  • 火眼取证+雷电模拟器深度联调实战指南
  • 宜春2026最新黄金回收本地口碑商家榜:黄金首饰+白银+铂金+彩金回收门店及联系方式推荐 - 前途无量YY
  • 告别C盘焦虑!手把手教你将WSL2的Ubuntu和CUDA环境迁移到D盘(附迁移后PyCharm连接完整流程)
  • 别再让Ubuntu卡成PPT了!手把手教你调整Swap分区大小(从1G到64G实战)
  • 可微分编程:连接物理仿真与机器学习的通用翻译器
  • Windows 10/11打印服务总自动停止?别慌,试试这5个修复步骤(附注册表清理指南)
  • Windows Server当NTP源?小心踩坑!详解W32Time配置与防火墙规则设置
  • Cursor内置浏览器遭恶意MCP服务器劫持:信任链攻防实战
  • kflash_gui:3分钟快速上手K210开发板固件烧录工具
  • 深入Debootstrap日志:手把手教你读懂Ubuntu根文件系统构建的每一个细节
  • ComfyUI-Manager下载加速终极指南:3步实现模型下载速度突破
  • 第七史诗自动化助手E7Helper:让游戏更轻松的全功能指南
  • 超越准确率:基于数据集特性的归一化性能度量设计与实践
  • SHAP可解释性分析在医疗AI决策中的应用:以肾脏移植预测为例
  • TinyML安全实战:从硬件攻击到模型防护的嵌入式AI安全指南
  • Rubish:纯 Ruby 编写的 UNIX shell,深度集成 Ruby 且功能强大!
  • 百度网盘批量转存终极指南:5分钟掌握高效文件管理技巧
  • Android Native逆向实战:Frida与IDA协同分析ART内存模型
  • 基于MultiFold无分箱反卷积的轻子-喷注方位角不对称性测量
  • 抖音批量下载器终极指南:如何3分钟搞定无损音乐提取与高效素材管理
  • 如何高效提取Wallpaper Engine资源?RePKG专业工具全解析
  • 手机号逆向查询QQ号:30秒快速找回遗忘账号的终极解决方案
  • ZXPInstaller终极指南:三分钟搞定Adobe插件安装的完整免费解决方案
  • 从留存率23%到76%:Lovable开发实践全链路,含可复用的8个情感化交互组件
  • 文档下载自动化终极解决方案:kill-doc浏览器脚本完全指南
  • Gofile极速下载器:3倍加速、断点续传的终极文件下载方案