Educational Codeforces Round 2 C. Make Palindrome —— 贪心 + 回文串

来源:互联网 发布:mac怎样整理文件 编辑:程序博客网 时间:2024/06/04 17:55

题目链接:http://codeforces.com/contest/600/problem/C


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



题解:

1.统计每个字母的出现次数。

2.最少操作次数:假设出现了奇数次的字母共有t个,则最少操作次数为t/2(除法为向下取整,下同),使得所有字母均出现偶数次(长度为偶数时),或者一个字母出现奇数次,其他字母出现偶数次(长度为奇数时)。

3.在操作次数为最小的情况下,尽可能降低总的ASCII值。即把ASCII值大且出现奇数次的字母变一个成ASCII值小且出现奇数次的字母,这样两种字母都出现偶数次了。

4.排列:按ASCII值从小到大,每个字母先输出sum[i]/2个,如果长度为奇数,则还需把中间的输出来,然后再按ASCII值从大到小,每个字母输出sum[i]/2个。




代码如下:

#include<bits/stdc++.h>using namespace std;typedef long long LL;const double eps = 1e-6;const int INF = 2e9;const LL LNF = 9e18;const int mod = 1e9+7;const int maxn = 2e5+10;int sum[30], len;char s[maxn];void init(){    scanf("%s",s+1);    len = strlen(s+1);    for(int i = 1; i<=len; i++)        sum[s[i]-'a']++;}void solve(){    int i = 0, j = 25;    while(i<j)    {        while(i<j && !(sum[i]&1)) i++;        while(i<j && !(sum[j]&1)) j--;        sum[i]++;        sum[j]--;    }    for(i = 0; i<=25; i++)    for(j = 1; j<=sum[i]/2; j++)        printf("%c",i+'a');    for(i = 0; i<=25; i++)    if(sum[i]%2)    printf("%c",i+'a');    for(i = 25; i>=0; i--)    for(j = 1; j<=sum[i]/2; j++)        printf("%c",i+'a');    cout<<endl;}int main(){    init();    solve();}


阅读全文
0 0
原创粉丝点击