健康)状况:
令S为从1开始连续编号的N个整数的序列。令S(L,R)表示由S中包含的连续元素组成的子序列,从编号为L的元素开始到编号为R的元素结束。我们需要找到这样的元素L和R的数量值,其中0 < L< R ≤ N,使得子序列S(L, R)的元素之和为奇数且负数。
在您的答案中,指出该子序列的长度(即该子序列中包含的元素数量)。如果有多个这样的子序列,请指出它们的最大长度。
输入数据
给出两个输入文件(文件 A(约 1000 个数字)和文件 B(约 300,000 个数字)),每个文件的第一行都包含数字 N (3 < N < 10,000,000) - 整数的数量。接下来的M行每一行包含一个绝对值不超过1000的整数。
在您的答案中,指明两个数字:首先是文件 A 的所需值,然后是文件 B 的所需值。
在输入文件中组织数据的典型示例
8
-73
153
35
0
-44
78
-69
2
使用这样的输入数据,问题条件通过 0 + (-44) + 78 + (-69) 和 0 + (-44) + 78 + (-69) + 2 之和满足。问题的答案是5号。
该问题有 2 个文件:for 和 for 300,000 个数字。
我的决定:
对于第一个文件,O(N^2)搜索算法是合适的。它不适合第二个,所以我尝试创建另一个。
这个想法是创建一个包含从第一个元素到第 i 个元素的所有元素之和的数组,以及 2 个包含偶数和奇数值的先前和的数组,其中每个元素都大于前一个元素。然后检查第一个数组的元素与具有不同奇偶校验的另一个数组的元素之间的差异。如果此差值小于 0,则继续进行下一个金额。
问题是,在 30,000 个元素之后,速度大大减慢,并且第二个文件的执行需要几个小时。谁能提出更好的解决方案?
我的代码
f = open('file.txt')
n = int(f.readline())
a = [int(f.readline())]
sums = [a[0]]
for i in f:
i = int(i)
a.append(i)
sums.append(sums[-1]+i)
mxs0 = [[], []]
mxs1 = [[], []]
k0 = []
k1 = []
for i in range(2,n):
if sums[i-2] % 2 == 0:
if len(k0) == 0:
k0.append(i-2)
elif k0[-1] < sums[i-2]:
k0.append(i-2)
if sums[i-2] % 2 == 1:
if len(k1) == 0:
k1.append(i-2)
elif k1[-1] < sums[i-2]:
k1.append(i-2)
mxs0.append(k0)
mxs1.append(k1)
lens = []
for i in range(2,n):
print(i)
if sums[i]%2==0:
if len(mxs1[i]) > 0 > sums[i]-sums[mxs1[i][-1]]:
for j in range(len(mxs1[i])):
if sums[i]-sums[mxs1[i][j]] < 0:
lens.append(a[mxs1[i][j] + 1:i + 1])
break
else:
if sums[i] < 0:
lens.append(a[0:i+1])
else:
if len(mxs0[i]) > 0 > sums[i]-sums[mxs0[i][-1]]:
for j in range(len(mxs0[i])):
if sums[i]-sums[mxs0[i][j]] < 0:
lens.append(a[mxs0[i][j] + 1:i + 1])
break
cc = 0
lens = [i for i in lens if type(i) != int]
for i in range(len(lens)):
cc = max(cc, len(lens[i]))
print(cc)