【tsinsen A1043】完美的代价(字符串处理+归并排序求逆序对)

A1043. 完美的代价
时间限制: 1.0s   内存限制: 512.0MB  
总提交次数: 1985   AC次数: 446   平均分: 44.86
问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出
3
【题解】【字符串处理+归并排序求逆序对】
【这道题的做法是求出将整个串反转需要的最小步数,然后因为是求到回文串的步数,所以除以二即可】
#include
#include
#include
#include
using namespace std;
char s[8010];
int d[8010],n,nxt[8010],pre[8010],a[8010],a1[8010],ans=0;
bool p[8010],t=true;
inline void js(int f,int m,int l)
{
    int i=f,j=m+1,k=f;
    while (i<=m&&j<=l)
    if(a[i]>a[j]) a1[k++]=a[j++],ans+=(m-i+1);
     else a1[k++]=a[i++];
    while(i<=m) a1[k++]=a[i++];
    while(j<=l) a1[k++]=a[j++];
    for(i=f;i<=l;++i) a[i]=a1[i];
    return;
}
inline void gb(int f,int l)
{
    if(f>s[i],d[s[i]-'a']++;//读入并记录每个字符出现了多少次 
    for(i=0;i<=25;++i)
     if(d[i]&1==1)
      if(!t) {printf("Impossible"); return 0;}
       else t=false;//因为是回文字串,所以最多只能出现一个出现次数为奇数的字符 
    memset(d,-1,sizeof(d));
    for(i=n-1;i>=0;--i) nxt[i]=d[s[i]-'a'],d[s[i]-'a']=i;//存每个字符的出现位置(当前位置存下一次出现的位置,倒着循环)
    memset(d,-1,sizeof(d));
    for(i=0;i


你可能感兴趣的:(排序,字符串,字符串)