poj 1854 Evil Straw Warts Live 变成回文要几次

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 1799 Accepted: 523

Description

A palindrome is a string of symbols that is equal to itself when reversed. Given an input string, not necessarily a palindrome, compute the number of swaps necessary to transform the string into a palindrome. By swap we mean reversing the order of two adjacent symbols. For example, the string "mamad" may be transformed into the palindrome "madam" with 3 swaps:
swap "ad" to yield "mamda"
swap "md" to yield "madma"
swap "ma" to yield "madam"

Input

The first line of input gives n, the number of test cases. For each test case, one line of input follows, containing a string of up to 8000 lowercase letters.

Output

Output consists of one line per test case. This line will contain the number of swaps, or "Impossible" if it is not possible to transform the input to a palindrome.

Sample Input

3
mamad
asflkj
aabb

Sample Output

3
Impossible
2

题意:一个字符串变成回文最少要几次

题解:
1、用回文的性质判断是否可以变成回文:个数为奇数的字母出现的次数小于等于1
2、从字符串的两端出发(l,r),在字符串两端同时找能使s[l]==s[r]的位置,
3、取使左右两端相等步数最少的那一端,并从内到外交换位置(若从外到内交换会疯狂WA)

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<stack>
#include<math.h>
#define mod 998244353
#define ll long long
#define MAX 0x3f3f3f3f
using namespace std;
int vis[26];
string s;

int check(string ss)
{
    int cnt=0;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<ss.length();i++)
        vis[ss[i]-'a']++;
    for(int i=0;i<26;i++)
    {
        if(vis[i]%2==1)
            cnt++;
    }
    if(cnt>1)
        return 1;
    else
        return 0;
}
int main()
{
    
    int n,ans;
    cin>>n;
    while(n--)
    {
        ans=0;
        cin>>s;
        if(check(s))
            cout<<"Impossible"<<endl;
        else
        {
            int len=s.length(),l,r,j,mid,x=MAX,y=MAX;

            for(int i=0;i<len/2;i++)
            {
                l=i;
                r=len-1-i;
                if(s[l]!=s[r])
                {
                    for(j=l+1;s[j]!=s[r];j++);
                    x=j;
                    for(j=r-1;s[j]!=s[l];j--);
                    y=j;
                    if(x-l>r-y)
                    {
                        ans=ans+r-y;
                        for(int j=y;j<r;j++)
                            s[j]=s[j+1];
                    }
                    else
                    {
                        ans=ans+x-l;
                        for(int j=x;j>l;j--)
                            s[j]=s[j-1];
                    }
                }
            }
            cout<<ans<<endl; 

        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/-citywall123/p/11216852.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值