7-7 完美的代价 (50 分)

回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。

交换的定义是:交换两个相邻的字符

例如mamad

第一次交换 ad : mamda

第二次交换 md : madma

第三次交换 ma : madam (回文!完美!)

输入格式:

第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)

第二行是一个字符串,长度为N.只包含小写字母

输出格式:

如果可能,输出最少的交换次数。

否则输出Impossible

输入样例:

5
mamad

输出样例:

3



#include<iostream>
#include<algorithm>
using namespace std;
int has[1009];
char s[100009];
int vis[100009];
int t;

int change(int x,int to){
    int ans=0;
    while(x!=to){
        swap(s[x],s[x+1]);
        ans++;
        x++;
    }
    return ans;
}


int find(int x,char a){
    for(int i=x;i;i--){
        if(s[i]==a) return i;
    }
    return 0;
}



int main(){
    scanf("%d",&t);
    scanf("%s",s+1);
    for(int i=1;i<=t;i++) has[s[i]]++;
    int ji=0;
    int jict=0;
    char jizf;
    for(int i='a';i<='z';i++){
        if(has[i]%2==1){
            ji++;
            jict=has[i];
            jizf=i;
            }
    }
    if(ji>1){
        cout<<"Impossible"<<endl;
        return 0;
    }
//    for(int i=1;i<=t/2;i++){
//        if(s[i]==jizf){
//            if(jict==1){
//
//                break;
//            }
//            else jict-=2;
//        }
//    }
        int ans=0;
        for(int i=1;i<=t/2;i++){
            int tem=find(t-i+1,s[i]);
            if(tem==i){
                for(int j=1;j<=t/2;j++){
                    swap(s[j],s[t-j+1]);
                }
                i--;
            }
            else{
                ans+=((t-i+1)-tem);
                change(tem,t-i+1);
            }
        }
        cout<<ans<<endl;
} 

 注意通过移动,奇数字符位置可能改变。

所以边处理边判断

01-19 14:30