在一行上输入一个长度为
,仅由大小写字母和数字构成的字符串
,代表截获的密码。
在一行上输出一个整数,代表最长的有效密码串的长度。
ABBA
4
在这个样例中,没有无关字符,所以最长的有效密码串就是
本身,长度为
。
12HHHHA
4
在这个样例中,最长的有效密码串是
,长度为
。
while True: try: zfc = input().strip() n = len(zfc) klb = [] for i in range(1, n + 1): loop = 0 while loop < n: a = zfc[loop:loop + i] klb.append(a) loop += 1 klb1 = [] for j in klb: for m in j: if m == j[-(j.index(m) + 1)]: klb1.append(len(j)) print(max(klb1)) except: break超内存怎么回事
while True:
try:
s=list(input())
count=0
if len(s)==2:
if s[0]==s[1]:
print(2)
else:
print(0)
else: #长度大于2的列表
for i in range(1,len(s)-1): #如果有一个的左边与右边相等,则把左边下标数字定为start
if s[i]==s[i+1]:
num=0#偶数成对
start=i
end=i+1#右边的字母下标定为end
while start>=0 and end<=(len(s)-1) and s[start]==s[end]:
start-=1 #start下标减一位
end+=1 #右边下标加一位
num+=2#顺便把长度加2
if num>count:#赋值count
count=num
if s[i-1]==s[i+1]:#如果是奇数的
num=1#奇数成对
start=i-1#左边下标为i-1
end=i+1#右边为i+1
while start>=0 and end<=(len(s)-1) and s[start]==s[end]: #end为右边的下标 一定只能为最后一位,并且左边等于右边
start-=1 #左减一
end+=1#右加一
num=num+2#长度加2
if num>count:
count=num#如果长度num大于count 赋值
print(count)
except:
break
import re def generate_pattern(n): part1 = ['([\\w])']*n part2 = ['\\'+ str(i) for i in range(n,0,-1)] part1.extend(part2) return ''.join(part1) while True: try: raw_input = input() n = len(raw_input)//2+1 while True: pattern = generate_pattern(n) res = re.findall(pattern, raw_input) if res: print(len(res[0])*2) break else: n -=1 if n==0: print(1) break except: break
def longest_echo(s): res = 1 # 至少为1 for i in range(1, len(s)-1): hf_odd, hf_even = 1, 1 try: while s[i-hf_odd] == s[i+hf_odd]: hf_odd += 1 except: pass try: while s[i-hf_even] == s[i+hf_even-1]: hf_even += 1 except: pass res = max(res, hf_even*2-2, hf_odd*2+1-2) # 条件退出的时候,需要-2(包括超界或不相等) return res import sys for line in sys.stdin: print(longest_echo(line.strip()))
# 改版 def zcHW(s): if s == s[::-1]: return len(s) s = list(s) newS = '#' + '#'.join(s) + '#' Len = len(newS) maxLen = [1] * Len # 默认自身为回文 for i in range(1,Len): # 对于索引i,前面有i个元素,索引为[0:i],后面有Len-i-1个元素,索引[i+1:Len] r = min(i, Len-i-1) # 能够达到的最大半径r m = 1 # 假设的初始半径 while m <= r: # 当前元素以半径为准,对左右两侧的元素逐一比对 if newS[i-m] == newS[i+m]: maxLen[i] = m m += 1 else: # 如果不相等了,跳出while循环,去判断下一个i break return maxLen while True: try: s = input().strip() maxLen = zcHW(s) print(max(maxLen)) except: break
while True: try: string = input() st = '' for i in range(len(string)): # 判断奇数长度回文子字符串,向两边扩散比较,碰到边界退出比较并输出 # 经过比较的回文子字符串,若输出的子字符串比先前判断的长则替换 l,r = i,i while l>=0 and r<len(string) and string[l] == string[r]: l -= 1 r += 1 temp = string[l+1:r] if len(temp) > len(st): st = temp # 判断偶数长度的回文子字符串,操作同奇数长度 l1,r1 = i,i+1 while l1>=0 and r1<len(string) and string[l1] == string[r1]: l1 -= 1 r1 += 1 temp = string[l1+1:r1] if len(temp) > len(st): st = temp print(len(st)) except: break
while True: try: s = input() dp = [0] * (len(s) + 1) for i in range(len(dp)): if i == 0 or i == 1: dp[i] = 1 else: ns = s[:i] s1 = ns[-(dp[i - 1] + 1):] s2 = ns[-(dp[i - 1] + 2):] if ns == ns[::-1]: dp[i] = i elif s1 == s1[::-1]: dp[i] = dp[i - 1] + 1 elif s2 == s2[::-1]: dp[i] = dp[i - 1] + 2 else: dp[i] = dp[i - 1] print(dp[-1]) except: break
可视化在: http://manacher-viz.s3-website-us-east-1.amazonaws.com/#/
import sys def calc_huiwen_length(string, s_len, center_id): cnt = 0 i = center_id - 1 j = center_id + 1 while i >= 0 and j < s_len: if string[i] == string[j]: cnt += 1 i -= 1 j += 1 else: break return cnt def manacher(ori_str): (1742)# 填错分隔符 # string = "" for i in range(len(ori_str)): string += "(1743)#%s" % ori_str[i] string += "#" s_len = len(string) maxlen = 0 (1744)# 回文串的中心点坐标 只能从 第二个至倒数第二个 for center_id in range(1, s_len-1, 1): tmp = calc_huiwen_length(string, s_len, center_id) maxlen = max(maxlen, tmp) print(maxlen) def isDuichen(string): i = 0 j = len(string) - 1 while i < j: if string[i] != string[j]: return False i += 1 j -= 1 return True def violence(ori_str): maxlen = 0 for i in range(len(ori_str)-1): for j in range(len(ori_str), i, -1): if isDuichen(ori_str[i:j]): curlen = len(ori_str[i:j]) maxlen = max(maxlen, curlen) print(maxlen) def solution(ori_str): manacher(ori_str) # 暴力解未通过,超时了 (1745)#violence(ori_str) for line in sys.stdin: solution(line.strip())
# -*- coding: utf-8 -*- # !/usr/bin/python3 # 解题思路:著名的马拉车算法,将时间复杂度从暴力搜索的O(n ^ 2)降低到了O(n) # 算法大概思路: # 1.预处理,在字符串的每个字符之间插入特殊字符,将字符串长度统一为奇数 # 2.从0开始遍历处理后的字符串,从当前字符向两边查找字符是否相等,计算回文半径 # 3.每次比较回文右边界和mx的大小,使用mx保存已探明的字符串右边界 # 4.如果遍历到位置i比mx大,那么i位置未知,半径为1,从i + 1和i - 1开始向两边找 # 5.如果遍历到位置i比mx小,说明i在上一次的回文范围之内,那么分两种情况 # 6.情况1:i关于上一次的回文中心对称的位置j,j的回文半径小于 mx - i,那么i的回文半径 >= j的回文半径 # 7.情况2:j的回文半径大于mx - i,那么i的回文半径 >= mx - i # 8.上述情况1是利用已探寻过得信息计算出i位置的已知信息,避免重复探寻 # 9.上述情况2是mx右侧位置信息未知,但是mx左侧信息已知,比年重复探寻 # 10.正是利用已探寻信息计算出已知信息避免重复探寻,将时间复杂度从2次方降低到了1次方 while True: try: s = input() ls = list(s) st = '#' + '#'.join(ls) + '#' # print(st) # 最长回文子串右边界 mx = 0 # 记录最新一次回文子串中心,非最长回文子串中心 flag = 1 # 各位置回文子串半径 dp = [1 for i in range(len(st))] # 记录最大st最大回文子串半径 lr = 0 for i in range(1, len(st)): if i < mx: dp[i] = min(mx - i, dp[2 * flag - i]) while i + dp[i] < len(st) and i - dp[i] >= 0 and st[i + dp[i]] == st[i - dp[i]]: dp[i] += 1 if dp[i] + i > mx: mx = dp[i] + i flag = i lr = max(lr, dp[i]) # print(st[flag - dp[flag] + 1:flag + dp[flag]]) print(lr - 1) except: break
def longestPalindrome(s): if s==s[::-1]:return len(s) maxLen=0 for i in range(len(s)): if i-maxLen>=1 and s[i-maxLen-1:i+1]==s[i-maxLen-1:i+1][::-1]: maxLen+=2 continue if i-maxLen>=0 and s[i-maxLen:i+1]==s[i-maxLen:i+1][::-1]: maxLen+=1 return maxLen while True: try: a=input() if a: print(longestPalindrome(a)) except: break
时间复杂度为O(n)
try: while(True): s = raw_input() MaxOdd = 1 for i in range(1,len(s)-1): j = 0 while i-j >=0 and i+j <= len(s)-1 and s[i-j] == s[i+j]: j += 1 if j > MaxOdd: MaxOdd = j MaxEven = 0 for i in range(1,len(s)-1): j = 0 while i-j>=0 and i+j+1<=len(s)-1 and s[i-j] == s[i+j+1]: j += 1 if j > MaxEven: MaxEven = j print max(2*MaxOdd-1, 2*MaxEven) except: pass