wa了好久,调了好久。。。。。
思路:先判断能否形成回文串,然后分治,先让整个串的两端字符相等,找出最少移动次数,然后去掉两端,得到新串,使新串两端相等,找出最小移动次数,这样不停缩小规模,直到搞完整个串。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN = 8010;
char str[MAXN];
int cnt[30],res;
bool bad()
{
memset(cnt,0,sizeof(cnt));
int len = strlen(str);
for(int i = 0; i < len; ++i)
++cnt[str[i]-'a'];
int cc = 0;
for(int i = 0; i < 26; ++i)
if(cnt[i]&1)
++cc;
return cc > 1;
}
void DAC(int l, int r)
{
if(l >= r) return;
if(str[l] != str[r])
{
//llen和rlen的初始化问题,wa了好久
int i,llen = r-l, lp = l, rlen = r-l, rp = r;
for(i = l; i < r; ++i)
if(str[i] == str[r])
{
llen = i-l;//记录交换次数
lp = i;
break;
}
for(i = r; i > l; --i)
if(str[i] == str[l])
{
rlen = r - i;
rp = i;
break;
}
if(llen < rlen)
{
res += llen;
for(int i = lp; i > l; --i)
swap(str[i],str[i-1]);
}
else
{
res += rlen;
for(int i = rp; i < r; ++i)
swap(str[i],str[i+1]);
}
}
DAC(l+1,r-1);
}
int main()
{
int T,len;
scanf("%d",&T);
while(T--)
{
scanf("%s",str);
len = strlen(str);
if(bad())
{
puts("Impossible");
continue;
}
res = 0;
DAC(0,len-1);
printf("%d\n",res);
}
return 0;
}
/*
a c b b a
0
*/