Make Palindrome CodeForces - 600C 思维题

题意

用最少的替换字母次数,将输入的字符串变成变成回文字符(如果相同的替换次数有多组解,输出字典序最小的一种),字母的位置可以任意改变(不计入次数)

思路

定义两个数组,一个数组记录每个字母出现的次数,另一个记录出现出现奇数次的字母,出现偶数次的不用改变,出现奇数次的从两边往中间遍历,使出现奇数次的字母  (小的加一  大的减一)变为偶数次 。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+11;
int main()
{
    char s[maxn];
    int h[26],v[30]={0};
    cin>>s;
    int n=strlen(s);
    int m=0;
    memset(h,0,sizeof(h));
    for(int i=0;i<n;i++)
    {
        h[s[i]-'a']++;
    }
    for(int i=0;i<26;i++)
    {
        if(h[i]%2!=0)
            v[m++]=i;
    }
    int k=0;
    for(int i=0,j=m-1;i<j;i++,j--) //将出现奇数次的字母改为偶数次  取两个奇数次字母中小的那一个
    {
        h[v[i]]++;
        h[v[j]]--;
    }
    if(n%2!=0)        //当输入字符串长度为奇数时 最后就会有一个字母出现奇数次取(出现奇数次字母中)中间那个
        s[n/2]=v[m/2]+'a';
    for(int i=0,j=n-1;i<j;i++,j--)
    {
        while(h[k]<=1)  //   会出现一次h[k]=1 的情况  且 k=v[m/2] 
             k++;
        if(h[k]>=2)
        {
            s[i]=k+'a';
            s[j]=k+'a';
            h[k]-=2;
        }
    }
    cout<<s<<endl;
    return 0;
}

借鉴了别人的代码才写出来的 。。。

猜你喜欢

转载自blog.csdn.net/qq_41837216/article/details/82526624