首页 > 试题广场 >

密码截取

[编程题]密码截取
  • 热度指数:262950 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些 \texttt{\texttt{\texttt{\texttt{
\hspace{15pt}但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 \texttt{\texttt{\texttt{ 。因为截获的串太长了,而且存在多种可能的情况( \texttt{ 可看作是 \texttt{\texttt{ 的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

输入描述:
\hspace{15pt}在一行上输入一个长度为 1 \leqq {\rm length}(s) \leqq 2500 ,仅由大小写字母和数字构成的字符串 s ,代表截获的密码。


输出描述:
\hspace{15pt}在一行上输出一个整数,代表最长的有效密码串的长度。
示例1

输入

ABBA

输出

4

说明

\hspace{15pt}在这个样例中,没有无关字符,所以最长的有效密码串就是 \texttt{ 本身,长度为 4
示例2

输入

12HHHHA

输出

4

说明

\hspace{15pt}在这个样例中,最长的有效密码串是 \texttt{ ,长度为 4
number = input()
num = number[::-1]

i = int(0)
j = int(len(number)-1)
s = 0
tt =[]
for i in range(len(number)):
    for j in range(len(number)):
        if i<j:
            if number[i:j+1in num:
                tt.append(number[i:j+1])
tt.sort()
result = ''
leng = 0
for s in tt:
   if len(s) > int(leng):
       leng = len(s)
       result = s

print(leng)
print(result)
发表于 2021-06-19 22:26:43 回复(0)
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
超内存怎么回事

发表于 2021-06-05 02:28:52 回复(0)

别人做的 我加一个注释也可以吧

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

发表于 2021-05-11 10:39:57 回复(0)
while 1 :
    try:
        s = input().strip()
        all_lst = []
        for i in range(len(s)):
            for j in range(i+1,len(s)+1):
                all_lst.append(s[i:j])
        res_lst = []
        for k in all_lst:
            if k[::-1] == k:
                res_lst.append(k)
        print(max(map(len, res_lst)))    
    except:
        break
这样内存超限。。。
发表于 2021-04-21 19:39:31 回复(0)
刚刚开创了一个新的思路,登顶Python!  发现用re速度最快
直接上代码:
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


发表于 2021-03-09 13:52:10 回复(0)
python3 的manacher居然比中心扩散法慢,为啥?
发表于 2021-02-26 17:37:34 回复(0)
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()))

发表于 2021-01-15 00:36:52 回复(0)
最长回文串问题
import sys


for s in sys.stdin:
    s = s.strip()
    max_l = 0
    for i in range(len(s)):
        if s[i-max_l:i+1] == s[i-max_l:i+1][::-1]:
            max_l += 1
        if i-max_l-1 >= 0 and s[i-max_l-1:i+1] == s[i-max_l-1:i+1][::-1]:
            max_l += 2
    print(max_l)


发表于 2020-12-15 21:25:20 回复(1)
while 1:
    try:
        a= list(input())
        count=0
        # 奇数
        for i in range(1, len(a)):
            j=1
            count1=1
            while (i-j>=0 and i+j<len(a)) and a[i-j]==a[i+j]:
                    count1 += 2
                    j += 1
            count = max(count, count1)
        # 偶数
        for i in range(0, len(a)-1):
            j=0
            if a[i]==a[i+1]:
                count2=0
                while (i-j>=0 and i+j+1<len(a)) and a[i-j]==a[i+1+j]:
                        count2 += 2
                        j +=1
                count = max(count, count2)
        print(count)
    except:
        break

编辑于 2020-11-18 22:57:12 回复(0)
python解法
# 改版
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

编辑于 2020-08-26 23:35:32 回复(0)
while True:
    try:
        num = input()
        n = len(num)
        count = 0
        while n >= 1:
            for i in range(len(num)-n+1):
                if num[i:i+n] == num[i:i+n][::-1]:
                    print(n)
                    count += 1
                    break
            if count == 1:
                break
            else: n -= 1
    except:
        break
这么做为啥就超时了呢?求大佬指点!谢谢~

发表于 2020-08-14 01:14:50 回复(1)
思路:遍历输入的字符串,以每一个元素为中心向两边扩散分别比较是否相等
回文子字符串有两种情况,分别为奇数长度(aba)和偶数长度(abba),因此需要分两种情况进行判断。
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


发表于 2020-08-09 11:02:39 回复(0)
python动态规划算法,复杂度 O
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


编辑于 2020-04-29 16:18:43 回复(0)
def palindrome(string):
    if not string:
        return 0
    res = ' '
    length = len(string)
    for i in range(length):
        res1 = helper(string, i, i)
        res2 = helper(string, i, i+1)
        res = res if len(res) > len(res1) else res1
        res = res if len(res) > len(res2) else res2
    return len(res)
    
def helper(string, left, right):
    length = len(string)
    while left >= 0 and right < length and string[left] == string[right]:
        left -= 1
        right += 1
    return string[left+1:right]

try:
    input_ = input()
    print(palindrome(input_))
except:
    import traceback
    traceback.print_exc()

这不是写对了吗? 怎么总是AC不掉。
发表于 2020-03-27 16:43:35 回复(0)
我的暴利解,时间复制度太高,貌似O(n^3)了
网上有一篇Manacher算法的可视化过程,照着实现了
 可视化在: 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())
    


编辑于 2020-03-07 18:21:34 回复(0)
# -*- 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

发表于 2019-11-26 16:24:40 回复(0)
对于我这种没学过算法的小白,能做出来一题要用专业算法解决的题真的是很开心了。
借鉴了manacher算法,程序第一部分是查找奇数回文串的(如aabaa),遍历每一个字符,从当前字符向两端查找,字符相同则num计数加二,ls记下每一个字符对应的回文串长度(num+1),最终输出ls中最大值。
第二部分是查找偶数回文串的(如bbaabb),遍历两个相同的字符串(如bb),向两端查找相同的字符,字符相同则num计数加二,ls记下每一个字符对应的回文串长度(num+2),最终输出ls中最大值。
while True:
    try:
        s=input().strip()
        lens=[]
        for i in range(1,len(s)):
            num=0
            for j in range(1,i+1):
                if i+j>=len(s):
                    break
                if s[i-j]==s[i+j]:
                    num+=2
                else:
                    break
            lens.append(num+1)
##        print(max(lens))
##-------------------------------------------------
        for i in range(1,len(s)):
            num=0
            if s[i]!=s[i-1]:
                continue
            else:
                for j in range(1,i+1):
                    if i-1-j<0:
                        break
                    if i+j>=len(s):
                        break
                    if s[i-1-j]==s[i+j]:
                        num+=2
                    else:
                        break
                lens.append(num+2)
        print(max(lens))
            
    except:
        break


发表于 2019-04-10 16:54:50 回复(1)

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)

编辑于 2017-10-04 17:50:27 回复(20)
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
编辑于 2017-01-09 12:02:54 回复(0)