美团校招-2023.3.18.10点-第三题-小美的回文串-简单

小美的回文串

Problem Description

现在小美获得了一个字符串。小美想要使得这个字符串是回文串。 小美找到了你。你可以将字符串中至多两个位置改为任意小写英文字符′a′− ′z′。 你的任务是帮助小美在当前制约下,获得字典序最小的回文字符串,数据保证能在题目限制下形成回文字符串。
注:回文字符串:即一个字符串从前向后和从后向前是完全一致的字符串。例如字符串abcba,aaaa,acca都是回文字符串。字符c串abcd,acea都不是回文字符串。

input

一行,一个字符串。字符串中仅由小写英文字符构成。 保证字符串不会是空字符串。 字符串长度介于[1,100000] 之间。

ouput

一行,一个在题目条件限制下所可以获得的字典序最小的回文字符串。

Sample Input 1

acca

Sample Output 1

aaaa
说明: 原来的字符串已经是回文字符串了。但它不是题目条件下可以取得的字典序最小的回文字符串。将第二个字符和第三个字符都改为a可以获得字典序最小的回文字符串。

Sample Input 2

abcde

Sample Output 2

abcba
说明 将de改为ba可以获得字典序最小的回文字符串。

题目类型、难度、来源

总体思路:

  • 暴力法。题目保证能最多改两个字符达成回文串。那么只有三种情况:
    • 有两个字符对(对称位置的两个字符)不对称。这种情况下必须用掉两次修改的机会,即把字符对中字典序较大的值改为较小的那个字符值。例如字符对为a,e,就要将e改为a。
    • 有一个字符对不对称。这种情况需要使用一次修改机会让字符串变为回文串,具体是把字符对中字典序较大的值改为较小的那个字符值。此时字符串已经回文了,再修改字符对会令字符串不再回文。为了不浪费修改机会,我们要看字符串长度是否是奇数,如果是奇数,就将中间的字符改为’a’。
    • 输入的字符串本身就是对称的。这种情况最简单,只要从左到右遍历字符串,将第一个字符对都改成’a’。

AC代码

#include <iostream>
#include <string>
using namespace std;
int main(){
    
    
    string s;
    cin >> s;
    int n = s.size();
    int cnt = 0, p1 = -1, p2 = -1;
    for (int i = n-1; i >= n/2; i--){
    
    
        if (s[i] == s[n-1-i])   continue;
        cnt++;
        if (cnt == 1){
    
    
            p1 = n-1-i;
        }else if (cnt == 2){
    
    
            p2 = n-1-i;
        }

    }
    if (cnt == 2){
    
    
        char c1 = min(s[p1], s[n-1-p1]);
        char c2 = min(s[p2], s[n-1-p2]);
        s[p1] = s[n-1-p1] = c1;
        s[p2] = s[n-1-p2] = c2;
    }else if (cnt == 1){
    
    
        char c1 = min(s[p1], s[n-1-p1]);
        s[p1] = s[n-1-p1] = 'a';
        if (c1 == 'a' && n%2==1){
    
    
            s[n/2] = 'a';
        }
    }else if (cnt == 0){
    
    
        for (int i = 0; i < n; i++){
    
    
            if (s[i] != 'a'){
    
    
                s[i] = s[n-1-i] = 'a';
                break; 
            }
        }
    }
    cout << s;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40735291/article/details/129686912