AT_arc113_c 题解

洛谷链接&Atcoder 链接

本篇题解为此题较简单做法较少码量,并且码风优良,请放心阅读。

1|0题目简述

现在有一个字符串 S,每一次你可以选择一个 i(1i|S|),如果 Si=Si+1Si+2。就可以将 Si+2 设为 Si

最多能操作几次。

2|0思路

本题比较贪心,让我们先来造一个样例解释一下:

abbfioidddssabsaa 最优的方案是:

  • 先操作 4 次变为 abbfioidddsssssss

  • 再操作 7 次变为 abbfioidddddddddd

  • 最后操作 14 次变为 abbbbbbbbbbbbbbbb

这样最大总操作次数25 次。

从这个样例中可以发现贪心思路,要想总操作次数最大化,就需要从后到前去操作,如果从前到后操作那么后面可操作的连续字母就会被覆盖,这样总操作次数就不是最大了。

对于每次操作,最优的是把后面的所有不相同的字母变为一样,这就涉及到一个问题,如果后面有相同字母如何判断?其实不必再从当前位置往后搜,只需要定义一个 num 一维数组用 numi 表示当前位置的后面字母 i 的个数

对于 num 数组需要在搜的过程中处理。如果遇到可以替换的情况就把当前位置后的字母全变为当前字母,同时需清空 num 数组的记录,把当前位置的字母数记录即可。

替换后,ans 需增加 ni,考虑到后面的相同字母,所以就需要用到我们维护num 数组了,所以操作数需减去 numstria

经过以上分析及优化后,很容易即可写出代码了:

#include<iostream> using namespace std; string str; long long ans = 0, num[205]; int main() { cin >> str; int n = str.length(); // 记录 str 的长度 num[str[n - 1] - 'a'] ++, num[str[n - 2] - 'a'] ++; // 初始化 num 数组 for(int i = n - 3; i >= 0; i --) { num[str[i] - 'a'] ++; // 记录此位置的字母 // 满足替换的条件 if(str[i + 1] != str[i + 2] && str[i] == str[i + 1]) { ans += n - i - num[str[i] - 'a']; for(int j = 0; j < 26; j ++) num[j] = 0; // 清空 num 数组 num[str[i] - 'a'] = n - i; // 记录替换后的字母数 } } cout << ans << endl; // 输出,换行好习惯 return 0; }

提交记录

The End!


__EOF__

本文作者So_noSlack
本文链接https://www.cnblogs.com/So-noSlack/p/17585866.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   So_noSlack  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示