代码执行时间限制的字符串排序问题



我最近试图解决一个HackerArth问题。代码处理了我给出的示例输入和一些自定义输入。但是,当我提交时,它显示了超过时限的错误。有人能解释一下我如何让代码运行得更快吗?

问题说明:循环移位

一个大的二进制数由大小为N的字符串A表示,由0和1组成。必须对此字符串执行循环移位。循环移位操作定义如下:

如果字符串A是[A0,A1,…,An-1],则在执行一个循环移位之后,字符串变为[A1,A2,…,Ann-1,A0]

您执行了无限次移位,每次都记录由字符串表示的二进制数的值。执行(可能为0(操作后形成的最大二进制数为B。您的任务是确定可以执行的循环移位的数量,以便字符串A表示的值在第K次等于B

输入格式:

第一行:表示测试用例数量的单个整数T对于每个测试用例:第一行:两个空格分隔的整数N和K第二行:表示字符串的A

输出格式:

对于每个测试用例,打印包含一个整数的单行,该整数表示执行的循环移位操作的数量,使得字符串a表示的值第K次等于B

代码:

import math

def value(s):
u = len(s)
d = 0
for h in range(u):
d = d + (int(s[u-1-h]) * math.pow(2, h))
return d

t = int(input())
for i in range(t):
x = list(map(int, input().split()))
n = x[0]
k = x[1]
a = input()
v = 0
for j in range(n):
a = a[1:] + a[0]
if value(a) > v:
b = a
v = value(a)
ctr = 0
cou = 0
while ctr < k:
a = a[1:] + a[0]
cou = cou + 1
if a == b:
ctr = ctr + 1
print(cou)

在这个问题中,对n的约束是0<n<1e5.在函数value((中,您可以从长度可达1e5的二进制字符串中计算整数。所以你计算的整数可以高达pow(2,1e5(。这肯定不切实际。

正如Prune所提到的,你必须使用一些有效的算法来找到一个子序列,比如sub1,它的重复组成了给定的字符串a。如果你用蛮力解决这个问题,时间复杂度将是O(n*n(,因为n的最大值是1e5,时间限制将超过。所以使用一些有效的算法。

我不能对你发布的代码做太多处理,因为你用毫无意义的变量和缺乏解释来混淆它。当我扫描它时,我得到的印象是,您已经采用了在长时间循环中进行个位数移位的简单方法。计算迭代次数,直到第K次达到B为止。

这很容易理解,但繁琐且效率低下。

由于循环在每次N迭代时都会重复,因此重复该过程不会获得新信息。您所需要做的就是找到在N迭代系列中遇到B的位置。。。其可以是多次。

为了使B出现多次,A必须由特定的比特子序列组成,重复2次或更多次。例如,101010011011。您可以在当前算法中添加一个简单的内容来检测这一点:在每次迭代时,检查当前字符串是否与原始字符串匹配。第一次达到这个值时,只需将重复因子计算为rep = len(a) / j。此时,退出移位循环:b的当前值是正确的。

既然已经有了b及其在第一次j旋转中的位置,就可以直接计算所需的结果,而无需进一步处理。

我希望你能在这里完成算法并进行编码。


Ah——作为需求描述,问题的措辞表明B是给定的。如果没有,则需要检测最大值。

要查找B,请将A附加到其自身。查找具有最大值的A长度字符串。您可以通过查找1s的最长字符串来加快这一过程,并对这些最大字符串之后的第一个0之后的值树应用其他众所周知的字符串搜索算法。

请注意,当您在A上迭代时,您会寻找重复原始值的第一个位置:这是所需的重复长度,它驱动了我答案的第一部分中的直接计算阶段。

最新更新