题目:http://www.tsinsen.com/A1043
所用的是贪心算法,如果让第一个位置用最小步数达到,那么就是找和第一个位置相同的字母,并且这个字母距离的最后一个位置最近。asmaasm,那么就将最后一个a冒泡到m后面。
第二个字母也是这样,最后一直整完,我先判断的是否能形成回文。如果是基数,那么我的算法会先让改点不动,弄完daass->dassa之后再将d归位。
伪代码:
1)判断是否形成回文;//不形成输出impossible并且退出
2)for(i=0;i<j;i++)//形成回文
j=n-coun-i;//coun探测到有个基数字母后,后半段与前半段对应的字母位置就变化了,反映在coun上,初始为1
在i到j之间找到与i相同的字母k
如果i=k说明是基数字母,不动他,coun=0,记录位置position。
如果i!=k那么两两对换直到k换到j的位置。想象成k冒泡到j,并且更新step。
if(position==-1)//未被修改
将所记录的position位置的换到j之前并且更新step。
#include <iostream>
#include <math.h>
using namespace std;
char s[8003];
int n;
bool po()
{
bool flag=false;
int abc[27];
for(int i=0; i<27; i++)
abc[i]=0;
for(int i=0; i<n; i++)
{
int u=s[i]-‘a‘;
abc[u]++;
}
for(int i=0; i<26; i++)
{
if(abc[i]%2!=0&&flag==false)
{
flag=true;
}
else if(abc[i]%2!=0&&flag==true)
{
cout<<"Impossible"<<endl;
return false;
}
}
return true;
}
int main()
{
int step=0;
cin>>n;
cin>>s;
int uniqu=-1;
int coun=1;
int i=0;
int j=n-coun-i;
if(po())
{
for(i=0; i<j; i++)
{
j=n-coun-i;
if(s[i]!=s[j])
{
int j2=j;
while(j2!=i&&s[j2]!=s[i])
j2--;
if(j2==i)
{
uniqu=i;
coun=0;
}
else
{
step=step+j-j2;
for(int k=j2; k<j; k++)
swap(s[k],s[k+1]);
}
}
}
if(uniqu!=-1)
{
for(int k=uniqu; k<j-1; k++)
swap(s[k],s[k+1]);
step=step+j-uniqu-1;
}
cout<<step<<endl;
//cout<<s<<endl;
}
return 0;
}
原文:http://www.cnblogs.com/SweetBeens/p/6341525.html