繁体   English   中英

来自2个范围的2个元素的总和将是一个给定的数字

[英]Sum of 2 elements from 2 ranges that will be one given number


我需要做一个快速算法(我已经做过一个很慢的算法),它将从两个整数范围(范围可以相交或不相交)中找到所有可能值的数量,总和就是给定的数量

我可以将其表示为一个方程: z = x + y
其中z是已知数,等于xy
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 <= bc <= 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 = 1b = 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM