我尽量不去寻求代码问题的帮助,除非我真的,真的,卡住了,这恰好是现在。
您的第一个任务是找到火星数据库的密码。为实现这一目标,您最好的秘密特工已经发现了以下事实: 密码是由一系列非递减数字组成的给定字符串的子字符串 密码尽可能长 密码始终是回文 回文是一个向后读取相同字符串的字符串。赛车,鲍勃和中午都是着名的例子。 鉴于这些事实,您能找到数据库的所有可能密码吗? 输入 第一行包含n,即输入字符串的长度(1≤n≤105)。 下一行包含一个长度为n的字符串。该字符串的每个字符都是一个数字。 字符串中的数字按非递减顺序排列。 产量 在第一行,打印可能的密码数k。 在接下来的k行中,按字母顺序打印可能的密码。
我的观察是:
非减少字符串中的回文只是一串重复字符(例如" 4444"或" 11")
关于字符i
,i的最后一个实例 - i +1的第一个实例=重复字符的长度
跟踪最大密码长度,然后过滤掉每个短于最大密码长度的项目,保证输出的密码长度最大
n,s = [input() for i in range(2)]#input
maxlength = 0
results = []
for i in s:
length = (s.rfind(i)-s.find(i))+1
if int(i*(length)) not in results and length>=maxlength:
results.append(int(i*(length)))
maxlength = length
#filer everything lower than the max password length out
results = [i for i in results if len(str(i))>=maxlength]
#output
print(len(results))
for y in results:
print(y)
不幸的是,这个解决方案是错误的,实际上并没有在第四个测试用例上失败。我不明白代码有什么问题,所以我无法解决它。有人可以帮忙吗?
感谢阅读!
答案 0 :(得分:2)
您的计划将失败:
4
0011
它只返回11
。
问题是str(int('00'))
的长度等于1.
您可以通过从程序中删除int
和str
来解决此问题(即将答案保存为字符串而不是整数)。
答案 1 :(得分:1)
Peter de Rivaz似乎已经确定了您的代码的问题,但是,如果您对解决此问题的其他方法感兴趣,请考虑使用正则表达式。
import sys
import re
next(sys.stdin) # length not needed in Python
s = next(sys.stdin)
repeats = r'(.)\1+'
for match in re.finditer(repeats, s):
print(match.group())
模式(.)\1+
将找到重复数字的所有子字符串。输入输出
10 3445556788
将是:
44 555 88
如果re.finditer()
发现没有重复的数字,则字符串为空,或者由一系列递增的非重复数字组成。排除第一种情况,因为 n 必须大于0.对于第二种情况,输入已按字母顺序排序,因此只输出长度和每个数字。
将它放在一起就可以得到这段代码:
import sys
import re
next(sys.stdin) # length not needed in Python
s = next(sys.stdin).strip()
repeats = r'(.)\1+'
passwords = sorted((m.group() for m in re.finditer(repeats, s)),
key=len, reverse=True)
passwords = [s for s in passwords if len(s) == len(passwords[0])]
if len(passwords) == 0:
passwords = list(s)
print(len(passwords))
print(*passwords, sep='\n')
请注意,匹配的子字符串是从match
对象中提取的,然后按长度降序排序。代码依赖于输入中的数字不得减少的事实,因此不需要第二种字母类型的候选密码。