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; }
注意通过移动,奇数字符位置可能改变。
所以边处理边判断