AT_agc022_a 题解

洛谷链接&Atcoder 链接

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

1|0题目简述

给定字符串 S , 仅包含互不相同的小写字母, 你需要找到仅包含互不相同的小写字母的字符串中,第一个字典序比它大的字符串, 如果找不到输出 1。(|S|26

2|0思路

这篇题解主要分享一下 map 的做法。

可分两种情况讨论:

  1. 字符串长度 <26

  2. 字符串长度 =26

因为互不相同所以不会出现大于 26 的情况。

对于样例 4abcdefghijklmnopqrstuvwzyx

可将 w 变为它后面比它大但最小x,后面直接舍去即可,变为 abcdefghijklmnopqrstuvx

解释完样例,先来讨论一下情况 1,因为长度小于 26,所以至少有 1 个字母未出现过,直接在字符串末尾加上没出现过最小字母即可。

对于情况 2,就可参考以上样例 4 的解释,可发现找到一个位置,把这个位置上的字母替换为它后面比它大但最小的字母即可,这个位置需要从后向前枚举

那么接下来就是实现了,首先需要定义一个 map 容器,来存储哪些字母出现过或没出现过,对于情况 1 直接模拟即可。

对于情况 2 则需记录一个最大值,如果当前位置小于最大值再枚举,这样就避免了不合法的情况了。

经过以上分类讨论,很容易即可写出代码了:

#include<iostream> #include<map> using namespace std; string str; int maxn; map<char, int> mp; map<int, bool> vis; int max(int x, int y) { return (x > y) ? x : y; } int main() { cin >> str; int n = str.length(); // 记录长度 for(int i = 0; i < n; i ++) mp[str[i]] ++; // 计数 if(n < 26) { for(int i = 'a'; i <= 'z'; i ++) if(!mp[i]) { cout << str << char(i) << endl; // 没有出现过,直接输出结束 return 0; } } // 从后向前枚举 for(int i = n - 1; i >= 0; i --) { // 满足条件,可输出 if(str[i] < maxn) { for(int j = 0; j < i; j ++) cout << str[j]; for(int j = str[i] - 'a'; j < 26; j ++) if(vis[j]) { cout << char(j + 'a'); // 输出替换的字母 return 0; } } maxn = max(maxn, str[i]); vis[str[i] - 'a'] = true; } cout << "-1\n"; // 以上条件都不满足,输出 -1 return 0; }

提交记录

The End!


__EOF__

本文作者So_noSlack
本文链接https://www.cnblogs.com/So-noSlack/p/17589323.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   So_noSlack  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示