【贪心】蓝桥杯-完美的代价

问题描述
  回文串,是一种特殊的字符串,它从左往右读和从右往左读是一样的。小龙龙认为回文串才是完美的。现在给你一个串,它不一定是回文的,请你计算最少的交换次数使得该串变成一个完美的回文串。
  交换的定义是:交换两个相邻的字符
  例如mamad
  第一次交换 ad : mamda
  第二次交换 md : madma
  第三次交换 ma : madam (回文!完美!)
  n<=8000
思路:
首先,对是否能构成回文串进行判定:

  • 若每个字母出现次数均为偶数,则能构成
  • 若有且仅有一个字母出现奇数次,则能构成
  • 否则,不能构成

接下来对能构成回文串的串使用贪心策略:

  • 为了防止重复,字母均采用从左至右单向交换
  • 处理区间为[0,mid],每次遇到一个字母,就去从字符串结尾未归位的位置往前开始找对应字母,将其向后交换至回文对应位置
  • 遇到出现奇数次的字母,且其查找到的字母位置与本字母位置相同,则先跳过此字母,将剩余字母处理完成之后,给总交换次数加上此字母交换至mid位置的交换次数,则得到答案

注:此代码由一组数据超时


n=0
ss=""
numCh=[0]*26
ans=0

def judge():
    for i in ss:    
        numCh[ord(i)-ord('a')]+=1
    # print(numCh)
    odd_i=-1
    odd_num=0
    t_len=len(ss)
    book=[0]*26
    for i in range(t_len):
        # if book[ord(ss[i])-ord('a')]==1:
        #     continue
        if numCh[ord(ss[i])-ord('a')]%2==1:
            if book[ord(ss[i])-ord('a')]!=1:
                odd_num+=1
            if odd_i==-1:
                odd_i=i
            elif abs(odd_i-t_len//2)>abs(i-t_len//2):
                odd_i=i
        book[ord(ss[i])-ord('a')]=1
    if odd_num>1:
        return False
    elif odd_num==1:
        global ans
    return True

def myFind(x,t_i):
    # t_i=len(ss)-1
    while(t_i>=0 and ss[t_i]!=x):
        t_i-=1
    return t_i
n=int(input())
ss=list(input())

if not judge():
    print("Impossible")
else:
    t_len=len(ss)
    midd=t_len//2
    t_flag=t_len-1
    if t_len%2==0:
        midd-=1
    i=0
    t_midd=midd

    while i<midd:
        t_ptr=myFind(ss[i],t_flag)
        if t_ptr==i:
            t_midd=i
            i+=1
            continue
        ans+=(t_flag-t_ptr)
        t_flag-=1
        for j in range(t_ptr,t_flag+1):
            ss[j],ss[j+1]=ss[j+1],ss[j]
        i+=1
    ans+=(midd-t_midd)
    print(ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值