uva10716 - Evil Straw Warts Live(转换成回文数)

如果有人说这道题是大水题,我无话可说

但是我不得不说的是这道题卡到我崩溃了。。。

思路正确就是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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值