zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 2 C. Make Palindrome —— 贪心 + 回文串

    题目链接: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个。



    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const double eps = 1e-6;
     5 const int INF = 2e9;
     6 const LL LNF = 9e18;
     7 const int mod = 1e9+7;
     8 const int maxn = 2e5+10;
     9 
    10 int sum[30], len;
    11 char s[maxn];
    12 
    13 void init()
    14 {
    15     scanf("%s",s+1);
    16     len = strlen(s+1);
    17     for(int i = 1; i<=len; i++)
    18         sum[s[i]-'a']++;
    19 }
    20 
    21 void solve()
    22 {
    23     int i = 0, j = 25;
    24     while(i<j)
    25     {
    26         while(i<j && !(sum[i]&1)) i++;
    27         while(i<j && !(sum[j]&1)) j--;
    28         sum[i]++;
    29         sum[j]--;
    30     }
    31 
    32     for(i = 0; i<=25; i++)
    33     for(j = 1; j<=sum[i]/2; j++)
    34         printf("%c",i+'a');
    35 
    36     for(i = 0; i<=25; i++)
    37     if(sum[i]%2)
    38     printf("%c",i+'a');
    39 
    40     for(i = 25; i>=0; i--)
    41     for(j = 1; j<=sum[i]/2; j++)
    42         printf("%c",i+'a');
    43     cout<<endl;
    44 }
    45 
    46 int main()
    47 {
    48     init();
    49     solve();
    50 }
    View Code
  • 相关阅读:
    java如何计算对象的大小
    java多线程实现主线程等待子线程执行完问题
    再次理解多线程线程安全问题(理解java内存模型后)
    关于局部变量在循环里的生存法则
    【CSS3】transform-origin原点旋转
    面向对象编程(本章小结)
    引入在线编程和编译站点
    关于获取素数 一个小程序
    C++ I/O
    HDU2571
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538654.html
Copyright © 2011-2022 走看看