题目描述:
给定一个只包含大写字母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
'''