消除重复字符得到的最大分数

题目描述:

给定一个只包含大写字母A、B、C的字符串s,消除过程是如下进行的:如果s包含长度超过1的由相同字母组成的子串,那么这些子串会被同时消除,余下的子串拼成新的字符串。字符串消除后,游戏最终得分是消除掉的字符的总数。

现在给你一个字符串,然后你可以选择在字符串任意位置,包括第一个字符之前和最后一个位置之后,插入A、B、C任意一个,问这个字符串能得到的最大分数是多少。


比如"ABCCBCCC",然后相邻的重复字符可以消去,最后得到"A".总共消去了7个字符,那么得分就是7。

思路:

暴力枚举+双指针+栈统计分数

代码实现

#暴力枚举+双指针+栈统计分数
s=list(input().strip())
def count_score(s_l:list[str]):
    #1、用栈+双指针来消除相邻相同字符并计算分数。
    #2、一直循环,直到分数不再增加后,结束循环。
    stack=[]
    his_score,cur_score=0,0
    while s_l:#如果全部消除,s_l为空[],就不用循环了
        r=0
        while r<len(s_l):
            # print(s_l, stack)
            if not stack:
                stack.append(s_l[r])
                if r<len(s_l)-1:
                    r+=1
                else:
                    break
            else:
                if s_l[r]!=stack[-1]:
                    stack.append(s_l[r])
                    if r<len(s_l):
                        r+=1
                    else:
                        break
                elif s_l[r]==stack[-1]:
                    cur_score+=1#栈尾部的重复字符
                    #开始向右找相同的字符
                    for n_r in range(r,len(s_l)+1):#为了防止s_l[-1]刚好也在重复字符里
                        if n_r==len(s_l):
                            # 为了防止s_l[-1]刚好也在重复字符里
                            r=n_r
                            break
                        if s_l[n_r]==stack[-1]:
                            cur_score+=1
                        else:
                            r=n_r
                            break
                    #此时r=n_r
                    stack.pop()

        #每轮循环完成后,进行判断与更新
        if cur_score>his_score:
            his_score=cur_score
            s_l=stack
            stack=[]
        else:
            return his_score

    #如果全部消除,直接退出外层循环,返回最大分数
    return his_score


def get_res(s:list[str]):
    insert_idx=None
    insert_sign=''
    max_score=0
    cmaxscore = 0
    for i in range(len(s)+1):
        n_s=s.copy()
        for j in list('ABC'):
            n_s.insert(i,j)
            cmaxscore=count_score(n_s)#在当前i处插入j的最大得分
            if max_score<cmaxscore:
                #如果有更大的分值出现,就更新插入的方式
                max_score=cmaxscore
                insert_idx=i
                insert_sign=j
            n_s.pop(i)#回溯
    return f'在索引:{insert_idx},插入字符:{insert_sign},得到最大分数:{max_score}'

print(get_res(s))

测试用例:

#用例

'''
CCABBAABCBCC
res:13


ABCCBCCC
res:9


ABCCBCCCAA
res:11
'''

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值