2016Y GDUT新生杯初赛 Problem H: 神奇的清华大大的神奇魔法

来源:互联网 发布:魔方教学软件 编辑:程序博客网 时间:2024/05/03 22:39

Problem H: 神奇的清华大大的神奇魔法

Description

清华大大很喜欢字符串,因为在他眼中,字符串有关的题目都可以轻松解决。 但是清华大大不喜欢不是回文串的字符串,因为如果一个字符串是回文串,意味着清华大大只读一半的字符串就可以了。 回文串是前后读结果相同的字符串,例如"p”, "abba"是回文串,而“ac”,“yt”则不是。 如果遇到非回文串字符,神奇的清华大大就会施展神奇的魔法,每次他可以消耗1个魔法值将该字符串中的一个字母变成另一个字母,或者消耗0个魔法值改变该字符串中各个字母的顺序。 现在有一个字符串(只含小写字母),请你告诉清华大大该如何做才能施展尽可能少的魔法值使它变成回文串。

Input

第一行为T,有T个样例。小于50。 接下来每行含有一个字符串,每个字符串长度小于200000。

Output

每行输出消耗最少魔法值所产生的回文字符串, 如果有多个结果,输出字典序最小的结果

Sample Input

2

aabc

aabcd

Sample Output

abba

 

 

分析解答:这题本质上是一个模拟题,但是加上了一个字典序最小,又带上了点贪心。

先记录26个字母的出现次数num[],若num[i]为奇数,且只有一个字母,那么可以直接输出

          若存在多个num[i]为奇数

          这时分两种情况:

          1.需要把其它字母改为当前字母;

          2.把该字母改为其它字母。

          为了得到最小字典序,我们贪心的选择将字典序大的字母改为字典序小的字母,按照这样的思维模拟下去。

上代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>using namespace std;char s[200005];int a[300];vector<int>q;int main(){    int T;    scanf("%d",&T);    while(T--)    {        q.clear();        memset(a,0,sizeof(a));        scanf("%s",s);        int len=strlen(s);        for(int i=0;i<len;i++)            a[s[i]]++;        for(int i='a';i<='z';i++)            if(a[i]&1)                q.push_back(i);        int size=q.size();        for(int i=0;i<size/2;i++)        {            a[q[i]]++,a[q[size-i-1]]--;        }        for(int i='a';i<='z';i++)            for(int j=1;j<=a[i]/2;j++)                putchar(i);        for(int i='a';i<='z';i++)            if(a[i]&1) putchar(i);        for(int i='z';i>='a';i--)            for(int j=1;j<=a[i]/2;j++)                putchar(i);        puts("");    }    return 0;}


0 0
原创粉丝点击