Make Palindrome

来源:互联网 发布:淘宝店以开启,怎么找货 编辑:程序博客网 时间:2024/06/05 02:07

Make Palindrome

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.

Example

InputaabcOutputabbaInputaabcdOutputabcba

题意:

给定一个字符串,要将它变为回文串,可以任意更改字符或者对已有字符交换位置。问,尽量少地更改字符(调换位置的次数不限),在最优的更改次数下,可以得到一个或多个回文串,输出其中字典序最小的那个回文串。

思路:

要让字典序最小,又要求得到回文串,那么必有成对出现的个数为奇数的字母,每次贪心地从最大的个数为奇数的字母中取出一个,把它变成最小的个数为奇数的字母,重复这个过程,直到所有的字母个数都为偶数(回文串长度为偶数),或者仅有一种字母个数为奇数(回文串长度为奇数)。这样,再将手头的字母按从小到大的顺序组成回文串,输出的字符串就是所求的解。

#include <iostream>#include <cstdio>#include <set>#include <string>#include <algorithm>#include <map>#include <vector>#include <utility>#include <cstring>using namespace std;char result[200001];int main() {#ifdef TEST    freopen("test.txt", "r", stdin);#endif // TEST    string sample;    while(cin >> sample) {        memset(result, 0, sizeof(result));        map<char, int> chmap;        vector<char> charVec;        int s, t;           int len = sample.length();           for(int i = 0; i < len; i++) {               if(!chmap.count(sample[i]))                   chmap[sample[i]] = 1;               else                   chmap[sample[i]]++;           }           for(auto it = chmap.begin(); it != chmap.end(); it++) {               if((it->second) & 1) {                   charVec.push_back(it->first);               }           }           sort(charVec.begin(), charVec.end());           int pos = 0;           int vecSize = charVec.size();           // 按升序取出了个数为奇数的字母放入vector中,从两边向中间取,将大的个数减一,小的个数加一。           while(pos < vecSize / 2) {               chmap[charVec[pos]]++;               chmap[charVec[vecSize - 1 - pos]]--;               pos++;           }           vector<pair<char, int> > resVec;           for(auto it = chmap.begin(); it != chmap.end(); it++) {               if(it->second) {                   resVec.push_back(*it);               }           }           int head = 0, tail = len - 1;           for(int i = 0; i < len / 2; i++) {               int j = 0;               while(resVec[j].second < 2 && j < resVec.size()) j++;               result[head++] = result[tail--] = resVec[j].first;               resVec[j].second -= 2;           }           if(len & 1) {               int j = 0;               while(!resVec[j].second && j < resVec.size()) j++;               result[len / 2] = resVec[j].first;           }           cout << result << endl;   }   return 0;}