1. 给定数组,求不与k整除的最长子串长度。
由于要频繁求和,使用前缀和数组;我们知道如果要最长子串的话,那么最长的肯定是从头到尾。
结合以上两点可以在计算前缀和数组的时候对每个元素对k取余数,然后进行遍历。如果当前前缀和不为0,那么更新最大长度;如果为0,那么去找第一个不为零的前缀和下标,更新最大长度。
n, k = map(int, input().split())
a = list(map(int, input().split()))
prefix = 0
min_index = float('inf')
max_length = 0
for i, ai in emuerate(a):
prefix = (prefix + ai) % k
if prefix != 0:
max_length = max(max_length, i + 1)
min_index = min(min_index, i)
else:
max_length = max(max_length, i + 1 - min_index)'
if max_length != 0:
print(max_length)
else:
print(-1)
2. 从一个长度为n的数组里随机抽取三个数,求和的期望
抽取的三个数总共有种可能,即分母为
,那么只需要将所有可能的和求出来就能够得到分子。但是三重嵌套循环会超时。
进一步分析,每一个元素会被被抽中几次,即n-1个元素中抽取两个元素有几种可能,即,所以分子一次循环即可搞定。
a = list(map(int, input().split()))
def gcd(a, b):
while b:
a, b = b, a % b
return a
mu = n * (n - 1) * (n - 2) // 6
zi = 0
for ai in a:
zi += (n - 1) * (n - 2) // 2 * ai
g = gcd(zi, mu)
print("{} {}".format(zi // g, mu // g))