【题解】构造回文串

题意

给你一个字符串,你可以将里面的字符改变成任意其他小写字母,要求在最小的更改次数下,使得更改后的串能重排出字典序最小的回文串。现在给你这个串,求修改次数最少重排后的回文串。

题解

改变和重排都不会变化字符串的长度,所以我们先考虑每个字母分别有多少个。为了构造回文串,除了中间字母所对应的字母个数可以为奇数个,其他字母应该都为偶数个。所以我们可以按照字典序先遍历字母,遇到一个奇数的字母其个数加一,我们再从逆字典序往回找,遇到第一个奇数时其个数减一。若字符中最多只有一个为奇数则退出。这样能保证能构造出字典序最小的字符串。那么除了唯一一个奇数字母,我们按顺序输出每个字符个数的二分之一,然后再倒转一下即可。

复杂度

时间复杂度

代码

#include <bits/stdc++.h>
using namespace std;
int vis[26];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis, 0, sizeof(vis));
        string str;
        cin>>str;
        int n=str.length();
        for(int i=0; i<n; i++)
            vis[str[i]-'a']++;
        for (int i = 0; i <26; i++)
        {
            if (vis[i]&1)
            {
                for (int j = 25; j >=0; j--)
                {
                    if (i == j)
                        continue;
                    if (vis[j]&1)
                    {
                        vis[j]--;
                        vis[i]++;
                        break;
                    }
                }
            }
        }
        char ch = '#';
        string ans = "";
        for (int i = 0; i < 26; i++)
        {
            if (vis[i] &1)
                ch = char(i + 'a');
            vis[i] /= 2;
            while (vis[i])
            {
                ans+=i + 'a';
                vis[i]--;
            }
        }
        cout << ans;
        if (ch != '#')
        {
            cout << ch ;
        }
        reverse(ans.begin(), ans.end());
        cout << ans << "\n";
    }
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 14:00
林子大了什么鸟都有啊,我觉得我说的已经很客气了,阴阳谁呢
牛客62656195...:应该不是阴阳吧?你第一次注册的时候boss就说你是牛人
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务