如果有人说这道题是大水题,我无话可说
但是我不得不说的是这道题卡到我崩溃了。。。
思路正确就是WA,
所以我就一直改,一直交,直到AC
说说我犯错的地方,
1、对于奇数次出现的字符处理不正确
2、对于字符串移动,出现了差错
要想A掉这道题,必须要想办法过了下面这道样例
input:aaabbbb
output:6
多点思考,多点认真,,,(只能对自己这么说了!!!)
代码如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
int main ()
{
char s[150];
int len, cas, ans, angle, f[30];
scanf("%d",&cas); getchar();
while(cas--)
{
scanf("%s",s); getchar();
len = strlen(s);
memset(f,0,sizeof(f));
for(int i = 0; i < len; i++) f[s[i]-'a']++; //奇数次出现的字符最多有一个
ans = 0;
for(int i = 0; i < 26; i++) ans+=f[i]%2;
if(ans>1) { puts("Impossible"); continue; }
int rear = 0, front = len-1, lr, lf;
ans = 0;
if(len%2)
{
int tt, cnt = 0;
for(int i = 0; i < len; i++) if(f[s[i]-'a']%2)
{ tt = f[s[i]-'a']; if(cnt++==tt/2) {s[i] = '*'; break;}}//改变奇数次出现的字符中最中间的字符的值
}
while(rear<=front)
{
if(s[rear]=='*') {angle = rear; rear++; continue;}
else if(s[front]=='*') {angle = front; front--; continue;}//如果是特殊字符就跳过。
for(int i = front; i > rear; i--) if(s[i]==s[rear]) {lr = front-i; break;}
for(int i = rear; i < front; i++) if(s[i]==s[front]){lf = i-rear; break; }//从两个方向找最小移动次数
if(lr<=lf)
{
ans+=lr;
for(int i = front-lr; i < front; i++) s[i] = s[i+1];
s[front] = s[rear];
}
else if(lf<lr)
{
ans+=lf;
for(int i = rear+lf; i > rear; i--) s[i] = s[i-1];
s[rear] = s[front];
}
rear++; front--;
}
if(len%2==0) printf("%d\n",ans);
else printf("%d\n",ans+abs(len/2-angle));
}
return 0;
}