您的位置:首页 > 其它

codeforce-600C. Make Palindrome(贪心)

2015-11-30 19:04 441 查看
http://codeforces.com/problemset/problem/600/C

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

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

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

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

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

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

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

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
int cmp(const void*p,const void*q);
char a[100005*2];
char b[100005*2];
char c[100005*2];
char bb[100005*2];
int aa[26];
#include<queue>
using namespace std;
int main(void)
{
int n,i,j,k,p,q,l,z;
while(scanf("%s",a)!=EOF)
{
queue<int>que;
z=0;
memset(aa,0,sizeof(aa));
l=strlen(a);
for(i=0; i<l; i++)//统计对应的字母有多少个
{
aa[a[i]-'a']++;
}
int t=0;
for(i=0; i<26; i++)
{
if(aa[i]!=0)
{
if(aa[i]>=2)//大于2的先加在串的两端
{
while(aa[i]>1)
{
aa[i]-=2;
a[t]=i+'a';
a[l-1-t]=i+'a';
t++;
z+=2;
}
}
if(aa[i]==1) que.push(i);//剩下1的入队

}

}
while(!que.empty())
{
int f=que.front();
que.pop();
if(z>=l)
{
break;
}
while(aa[f]>0)
{
aa[f]-=2;
a[t]=f+'a';
a[l-1-t]=f+'a';
t++;
z+=2;
if(z>l)
{
break;
}
}
if(z>=l)//当满了就跳出
{
break;
}
}
int uu;
if(l%2==0)//找串的一半(分奇数偶数讨论)
{
uu=l/2;
}
else uu=(l-1)/2;
for(i=0; i<uu; i++)
{
b[i]=a[i];
}
qsort(b,uu,sizeof(char),cmp);//对串的一半排序
for(i=0; i<uu; i++)
{
printf("%c",b[i]);
}
if(l%2==1)
{
printf("%c",a[(l)/2]);
}
for(i=uu-1; i>=0; i--)
{
printf("%c",b[i]);
}
printf("\n");

}
return 0;
}
int cmp(const void*p,const void*q)
{
char *w=(char*)p;
char *u=(char*)q;
return (*w-'a')-(*u-'a');
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: