CodeForces

来源:互联网 发布:齐次变换矩阵的定义 编辑:程序博客网 时间:2024/06/03 22:54

C. Make Palindrome
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A string is called palindrome if it reads the same from left to right and from right to left. For example "kazak", "oo", "r" and "mikhailrubinchikkihcniburliahkim" are palindroms, but strings "abb" and "ij" are not.

You are given string s consisting of lowercase Latin letters. At once you can choose any position in the string and change letter in that position to any other lowercase letter. So after each changing the length of the string doesn't change. At first you can change some letters in s. Then you can permute the order of letters as you want. Permutation doesn't count as changes.

You should obtain palindrome with the minimal number of changes. If there are several ways to do that you should get the lexicographically (alphabetically) smallest palindrome. So firstly you should minimize the number of changes and then minimize the palindrome lexicographically.

Input

The only line contains string s (1 ≤ |s| ≤ 2·105) consisting of only lowercase Latin letters.

Output

Print the lexicographically smallest palindrome that can be obtained with the minimal number of changes.

Examples
input
aabc
output
abba
input
aabcd
output
abcba


可以将一个字母切换成任意字母,然后还可以排序,排序还不算切换次数,典型的贪心

代码

#include<iostream>#include<cstdio>#include<cstring>using namespace std;char s[200005];int num[30];//总共只有26个小写字母,用数组存每个字母出现的次数int add[30];//待处理数组int main(){    while(~scanf("%s",s))    {        int label=0;        memset(add,0,sizeof add);        memset(num,0,sizeof num);        int n = strlen(s);        for(int i = 0;i < n;i++){            num[s[i]-'a'+1]++;        }        int k=0;        for(int i = 0;i < 30;i++){  //按字典序遍历,免去了排序操作            if(num[i]%2){   //如果该字母出现的次数为奇数次,那么它就有可能(baaab也是回文串)是要改变成其他字母的                add[k]=i;   //将该字母对应的编号放入待处理数组中                k++;            }        }        k--;//此时k的值就是待处理数组中待处理元素的个数,减一是因为可以留一个出现奇数次的字母放在回文串中间,比如有abcde,就只需要改abde四个就好        for(int i = 0;i <= k/2;i++)将字典序在后面的字母改成字典序较大的字母,然后更改它们出现的次数,这样最后num数组就是各元素在最终回文串中出现的次数        {            num[add[i]]++;            num[add[k-i]]--;        }        for(int i = 1;i < 30;i++){//先输出前一半            if(num[i]%2){                label=i;            }            if(num[i]){                char temp='a'+i-1;                for(int j = 0;j<num[i]/2;j++) printf("%c",temp);            }        }        if(label){//如果有的话就输出一个出现奇数次的字母在回文串中间            char temp='a'+label-1;            printf("%c",temp);        }        for(int i = 26;i > 0;i--){//输出后一半            if(num[i]){                char temp='a'+i-1;                for(int j = 0;j<num[i]/2;j++) printf("%c",temp);            }        }        printf("\n");    }    return 0;}