codeforce-600C. Make Palindrome(贪心)

http://codeforces.com/problemset/problem/600/C

题意:给你一个小写字母组成的英文串,将它转换为回文串,要求,改变的字母的个数最小,移动字母不算改变字母。

所得的串字典序是最小的。最后输出所得到的串。

思路:要求改变的字母数最小那么用贪心的思想,就把原来的字母尽可能多的填入要求的串中。

首先,先把原串中的字母统计出来,开个数组存对应的字符的个数,然后从‘a’开始循环,如果对应字母的个数大于1;

如果是偶数个的话,就在所求串两端一边加一个,可以正好加完,若是奇数个的话那么按这样的操作,最后就剩下一个,那么把它加入队列。

最后操作队列中的单个的,然后补一个加到串的两端,直到串被补满。

然后再对串的一半排下序就可以了。

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 int cmp(const void*p,const void*q);
  6 char a[100005*2];
  7 char b[100005*2];
  8 char c[100005*2];
  9 char bb[100005*2];
 10 int aa[26];
 11 #include<queue>
 12 using namespace std;
 13 int main(void)
 14 {
 15     int n,i,j,k,p,q,l,z;
 16     while(scanf("%s",a)!=EOF)
 17     {
 18         queue<int>que;
 19         z=0;
 20         memset(aa,0,sizeof(aa));
 21         l=strlen(a);
 22         for(i=0; i<l; i++)//统计对应的字母有多少个
 23         {
 24             aa[a[i]-'a']++;
 25         }
 26         int t=0;
 27         for(i=0; i<26; i++)
 28         {
 29             if(aa[i]!=0)
 30             {
 31                 if(aa[i]>=2)//大于2的先加在串的两端
 32                 {
 33                     while(aa[i]>1)
 34                     {
 35                         aa[i]-=2;
 36                         a[t]=i+'a';
 37                         a[l-1-t]=i+'a';
 38                         t++;
 39                         z+=2;
 40                     }
 41                 }
 42                 if(aa[i]==1) que.push(i);//剩下1的入队
 43 
 44             }
 45 
 46 
 47         }
 48         while(!que.empty())
 49         {
 50             int f=que.front();
 51             que.pop();
 52             if(z>=l)
 53             {
 54                 break;
 55             }
 56             while(aa[f]>0)
 57             {
 58                 aa[f]-=2;
 59                 a[t]=f+'a';
 60                 a[l-1-t]=f+'a';
 61                 t++;
 62                 z+=2;
 63                 if(z>l)
 64                 {
 65                     break;
 66                 }
 67             }
 68             if(z>=l)//当满了就跳出
 69             {
 70                 break;
 71             }
 72         }
 73         int uu;
 74         if(l%2==0)//找串的一半(分奇数偶数讨论)
 75         {
 76             uu=l/2;
 77         }
 78         else uu=(l-1)/2;
 79         for(i=0; i<uu; i++)
 80         {
 81             b[i]=a[i];
 82         }
 83         qsort(b,uu,sizeof(char),cmp);//对串的一半排序
 84         for(i=0; i<uu; i++)
 85         {
 86             printf("%c",b[i]);
 87         }
 88         if(l%2==1)
 89         {
 90             printf("%c",a[(l)/2]);
 91         }
 92         for(i=uu-1; i>=0; i--)
 93         {
 94             printf("%c",b[i]);
 95         }
 96         printf("
");
 97 
 98     }
 99     return 0;
100 }
101 int cmp(const void*p,const void*q)
102 {
103     char *w=(char*)p;
104     char *u=(char*)q;
105     return (*w-'a')-(*u-'a');
106 }
油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/5008089.html