蓝桥杯练习 BASIC-19 完美的代价

题目链接:http://lx.lanqiao.cn/problem.page?gpid=T60

基础练习 完美的代价
时间限制:1.0s 内存限制:512.0MB

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
输入格式
  第一行是一个整数N,表示接下来的字符串的长度(N <= 8000)
  第二行是一个字符串,长度为N.只包含小写字母
输出格式
  如果可能,输出最少的交换次数。
  否则输出Impossible
样例输入
5
mamad
样例输出
3

思路

先特判不可能变成回文串的情况。

如果能变成回文串:(n为奇数且落单字符个数为1 或者 n为偶数且没有落单字符)
模拟, 一个指针 i 从左往右遍历,设 i 的对称位置为 k ,每次相当于先固定 i ,设一个指针 p 从右往左遍历(从 k 到 i+1)找与a[i]相同的字符。

找到时停止,此时与a[i]相同的字符的位置为p,把a[p]一直向右交换到a[k],这样就能使 a[i]=a[k];

但如果找不到与a[i]相同的字符,说明a[i]是落单的,这时需要把a[i]和a[i+1]交换一次,再找与新的a[i]相同的字符的位置,这时就一定能找到与新的a[i]配对的字符了(因为n为奇数才能有落单字符且落单字符个数为1,原a[i]是落单字符,则原a[i+1]一定不是落单字符)。

AC代码

#include <bits/stdc++.h>
using namespace std;
int n,p,k,ans,flag,vis[30];
char a[8010];
bool judge()
{
    int cnt=0;
    for(int i=1;i<=26;i++)
    {
        if(vis[i]%2==1)cnt++;//落单的个数为cnt(不是成对出现的)
        if(n%2==1&&cnt>1)return 1;
        if(n%2==0&&cnt>0)return 1;
    }
    return 0;

}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>a+1;
    for(int i=1;i<=n;i++)
        vis[a[i]-'a'+1]++;
    if(judge())printf("Impossible\n");
    else
    {
        for(int i=1;i<=n/2;i++)
        {
            k=n+1-i;//k为对称位置
            if(a[k]!=a[i])
            {
                flag=0;
                for(p=k-1;p>i;p--)//p用来找与a[i]相同的字符的位置,从后往前找
                    if(a[p]==a[i]){flag=1;break;}
                if(flag==0)//找不到与a[i]相同的字符,说明a[i]落单了,把它与a[i+1]交换
                {
                    swap(a[i],a[i+1]);
                    ans++;
                    i--;//交换后再从新的a[i]开始循环,回退一次,把i--
                    continue;
                }
                for(;p<k;p++)//把a[p]与相邻的后一个字符a[p+1]交换,一直交换到i的对称位置k
                {
                    swap(a[p],a[p+1]);
                    ans++;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

附赠测试数据:

输入
97
eugygmammdetxltuvttfhwliqdmbflrlgirrnfejwcwjrhleelnqduvbnardaanseedkkyowzkzgknksokgdzxgznfecwrubw
输出
990

发布了72 篇原创文章 · 获赞 91 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ljw_study_in_CSDN/article/details/102797672