【问题标题】:Sum of 2 elements from 2 ranges that will be one given number来自 2 个范围的 2 个元素的总和,这将是一个给定的数字
【发布时间】:2015-12-06 02:48:27
【问题描述】:


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

我可以将其表示为等式:z = x + y
其中 z 是一个已知数,等于 x 加上 y
z 可以是 0 到10^18

x 属于整数范围 [a..b],其中 0 连续数字之间的差是1

y 属于整数范围 [c..d],其中 0 连续数字之间的差是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

【问题讨论】:

    标签: python algorithm


    【解决方案1】:

    不需要算法——只需要代数:

    计算[a,b]z - x[c,d] 中的x 的数量就足够了

    您需要a &lt;= x &lt;= bc &lt;= z - x &lt;= d。第二个不等式相当于z - d &lt;= x &lt;= z - c 因此你需要

    max(a, z - d) <= x <= min(b,z - c)
    

    这样的x的数量是0如果min(b,z - c) &lt; 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】:

      您可以用来减少算法检查的一件事是,

      如果 2 个集合的范围重叠,那么您可以取消一些检查。就像你的例子一样,

      第一组的范围是 1 到 5

      第二组的范围是 1 到 5

      如果

      x = 4, y = 1
      

      正在工作,然后

      x = 1, y = 4
      

      也可以。所以你只需要到一半的数字(即在这种情况下只到 3)


      如果只有一部分范围重叠,那部分可以用上面的方法,剩下的部分可以用普通方法检查。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多