codeforce708A-Letters Cyclic Shift

本文探讨了如何通过仅对给定字符串的一个非空子串进行字母循环左移操作('a'转为'z'例外),来获取字典序最小的新字符串。介绍了算法思路并提供了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Letters Cyclic Shift
Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Appoint description: 

Description

You are given a non-empty string s consisting of lowercase English letters. You have to pick exactly one non-empty substring of s and shift all its letters 'z 'y 'x 'b 'a 'z'. In other words, each character is replaced with the previous character of English alphabet and 'a' is replaced with 'z'.

What is the lexicographically minimum string that can be obtained from s by performing this shift exactly once?

Input

The only line of the input contains the string s (1 ≤ |s| ≤ 100 000) consisting of lowercase English letters.

Output

Print the lexicographically minimum string that can be obtained from s by shifting letters of exactly one non-empty substring.

Sample Input

Input
codeforces
Output
bncdenqbdr
Input
abacaba
Output
aaacaba

Hint

String s is lexicographically smaller than some other string t of the same length if there exists some 1 ≤ i ≤ |s|, such that s1 = t1, s2 = t2, ..., si - 1 = ti - 1, and si < ti.


从仅有小写字母组成的字符串s中挑选出一个非空子串

将该子串中的每个字母均替换成前一个字母,如'b'换成'a','c'换成'b',以此类推,特别的,'a'要换成'z'

问经过一次转换之后,字典序最小的字符串s为多少

首先,何为字典序最小,大家应该都理解

然后,题目的替换操作,很明显会将字符串s的字典序变小,但是唯一一个特例是字母'a',它替换之后反而会使得字典序变小

于是乎,字母'a'成了突破口,凡是遇到字母'a',能不替换就不替换

也就意味着,我们要替换除'a'之外的其他字母


上述这种,能够替换的有两部分,红色虚线及绿色虚线,从字典序大小考虑出发,越靠前的字母变小,整体字典序越小

所以,我们会替换红色虚线处的字母,而不是绿色虚线处的字母


当然,此题最值得注意的是"exactly one non-empty substring"

这就意味着全'a'串也要变,即字符串"aaaaaaa",我们要替换其中的字母(会使得字典序比原来大),但又要使字典序最小,所以只能将最后一个'a'->'z'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[1000005];
int main()
{
	
	while(~scanf("%s",&s))
	{
		int l=strlen(s);
		int t=0;
		for(int i=0;i<l;i++)
			{
				if(s[i]!='a'&&t==0)
			{
				s[i]=s[i]-1;
				t=1;
			}
			else if(t&&s[i]=='a') break;
			else if(t&&s[i]!='a') s[i]--;	
			}
			if(t==0) s[l-1]='z';
		printf("%s",s);
		printf("\n");		
		
	}
	return 0;
 } 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值