CodeForces 600C Make Palindrome (模拟题)

来源:互联网 发布:java float 精度 编辑:程序博客网 时间:2024/05/21 08:54
C - Make Palindrome
Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Submit Status Practice CodeForces 600C

Description

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.

Sample Input

Input
aabc
Output
abba
Input
aabcd
Output
abcba

题意是,给你一个操作,即改变字符,让你实现,以最少的操作次数使字符串变为回文串,其中可以自由改变字符串的顺序,不算在操作次数中,同时如果有多个字符串满足条件,请输出字典序最小的回文串。

解法:
首先可以知道,字符个数为偶数的字符是不需要进行转换,由于可以自由改变字符串的顺序并且不算在操作中,所以只要是偶数的字符那么久不需要进行转换,接下来是奇数个字符,只要遵循一个选择,能够转换为小的字符,那么就先进行转换。
然后就是对于特殊判断的字符串的长度一个为奇一个为偶,对于奇数的,我们就是要找到最小的顶点(即字符串中心部分的字符必须是最小的)。提醒一下,不是中间为'a'就是最小的,原因就是我们是要满足了最小操作然后才要满足字典序最小。
#include <bits/stdc++.h>using namespace std;#define pb push_back#define mp make_pair#define fillchar(a, x) memset(a, x, sizeof(a))#define copy(a, b) memcpy(a, b, sizeof(a))typedef long long LL;typedef pair<int, int > PII;typedef unsigned long long uLL;template<typename T>void print(T* p, T* q, string Gap = " ") {    int d = p < q ? 1 : -1;    while(p != q) {        cout << *p;        p += d;        if(p != q) cout << Gap;    }    cout << endl;}template<typename T>void print(const T &a, string bes = "") {    int len = bes.length();    if(len >= 2)cout << bes[0] << a << bes[1] << endl;    else cout << a << endl;}const int INF = 0x3f3f3f3f;const int MAXM = 2e4 + 5;const int MAXN = 2e5 + 5;char Str[MAXN];char X[MAXN];int vis[255];int main() {    while(~scanf("%s", Str)) {        int len = strlen(Str), num = 0;        for(int i = 0; i < len; i ++) {            vis[Str[i]] ++;        }        for(char i = 'a'; i <= 'z'; i ++) {            if(vis[i] & 1) num ++;        }        num >>= 1;        bool flag = false;        int top = 0;        for(char i = 'a'; i <= 'z'; i ++) {            if(vis[i] & 1) {                if(num) {                    vis[i] ++,num --;                } else {                    if((len & 1)&& !flag) {                        top = i;                        flag = true;                    } else {                        vis[i] --;                    }                }            }        }        int cnt = 0;        for(char i = 'a' ; i <= 'z'; i ++) {            while(vis[i] >= 2) {                X[cnt] = i;                X[len - cnt - 1] = i;                vis[i] -= 2;                cnt ++;            }        }        if(len & 1) X[len >> 1] = top;        X[len] = '\0';        print(X);    }    return 0;}


1 0