![](/img/trans.png)
[英]list of elements from a list that sum is equal or less than to a given number
[英]Sum of 2 elements from 2 ranges that will be one given number
我需要做一个快速算法(我已经做过一个很慢的算法),它将从两个整数范围(范围可以相交或不相交)中找到所有可能值的数量,总和就是给定的数量
我可以将其表示为一个方程: z = x + y
其中z是已知数,等于x加y
z可以是0到10 ^ 18之间的任何数字
x属于整数[a..b]的范围,其中0 <= a <= b <= 10 ^ 18
连续数字之间的差为1
y属于整数[c..d]的范围,其中0 <= c <= d <= 10 ^ 18
连续数字之间的差为1
所以我需要从两组总和为z的数字中找到x和y的所有可能变化的数字(而不是它们的确切值)
例:
z = 5
第一组:a = 1,b = 5(这意味着该组由1,2,3,4,5组成)
第二组:c = 1,b = 5
那么答案是4,因为所有可能的组合都是:
x = 4,y = 1
x = 3,y = 2
x = 2,y = 3
x = 1,y = 4
因为他们的总和是5
算法的强制性条件是工作时间超过1秒
下面的代码可以正常工作,但只能用于小于1000000的数字。对于大数字,它的运行速度将慢得多
with open(r"input.txt") as f:
n = int(f.readline()) # the given number
a = int(f.readline()) # the start position of the first set
b = int(f.readline()) # the end position of the first set
c = int(f.readline()) # the start position of the second set
d = int(f.readline()) # the end position of the second set
# print "n:",n,"a:",a,"b:",b,"c:",c,"d:",d
t = b - a + 1 # all posible variants of the first set
k = d - c + 1 # all posible variants of the second set
number_of_vars = 0
if t >= k:
while b >= a:
if (n - b <= d) \
and (n - b>= c):
number_of_vars += 1
b -= 1
else:
b -= 1
if t < k:
while d >= c:
if (n-d <= b) and (n-d >= a):
number_of_vars += 1
d -= 1
else:
d -= 1
print number_of_vars
无需算法-仅代数:
只需计算[a,b]
中x
的数量,其中z - x
在[c,d]
您需要a <= x <= b
和c <= z - x <= d
。 第二个不等式等于z - d <= x <= z - c
因此您需要
max(a, z - d) <= x <= min(b,z - c)
如果min(b,z - c) < max(a, z - d)
则x
的个数为0
min(b,z - c) < max(a, z - d)
否则为
min(b,z - c) - max(a, z - d) + 1
无论哪种情况,解决方案的数量都是
max(0, min(b,z - c) - max(a, z - d) + 1)
在您的示例中, a = c = 1
和b = d = z = 5
且
min(b, z - c) - max(a, z - d) + 1 = min(5,4) - max(1,0) + 1 = 4 - 1 + 1 = 4
您可以用来减少算法检查量的一件事是,
如果2套的范围重叠,则可以取消一些检查。 就像您的示例一样
第一组的范围是1到5
第二组的范围是1到5
因此,如果
x = 4, y = 1
正在工作,然后
x = 1, y = 4
也可以。 因此,您只需要走到一半的数目(在这种情况下,只走到3个)
如果范围的仅一部分重叠,则可以对该部分使用上述方法,而其余部分可以使用常规方法进行检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.