向前走莫回头❤

【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<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
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<l)
     {
        int m=(f+l)/2;
        gb(f,m); gb(m+1,l);
        js(f,m,l);
    } 
  return;
}//归并排序求逆序对 
int main()
{
    int i;
    scanf("%d",&n);
    for(i=0;i<n;++i)  cin>>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<n;++i) pre[i]=d[s[i]-'a'],d[s[i]-'a']=i;//存每个字符出现的位置(当前位置存上一次出现的位置,正着循环)
    memset(p,false,sizeof(p));
    for(i=0;i<n;++i)
     if(!p[i])
      {
        int u=i,v=d[s[i]-'a'];
        while(v!=-1)
         {
            a[n-u-1]=v;
            p[u]=true;
            u=nxt[u]; v=pre[v];//指针后移(u代表的是翻转后的字串) 
        }
       }//为每个位置的字符编号(按它完全倒置后的样子编),取最近的一个位置的当前字符(因为每次只能向左或向右移动一个单位,为了保证步数尽可能小) 
    gb(0,n-1);//归并排序求逆序对 
    printf("%d\n",ans/2);//因为是求到回文的步数,所以相当于只变一半 
    return 0;   
}//从1开始存就错,不知为什么…… 


 

 

posted @ 2016-11-17 17:30  lris0-0  阅读(145)  评论(0编辑  收藏  举报
过去的终会化为美满的财富~o( =∩ω∩= )m