【问题标题】:Efficient algorithm to count the numbers in range [L,R] that are divisible by at least one prime number in range [1,N]计算 [L,R] 范围内可被 [1,N] 范围内至少一个素数整除的数字的高效算法
【发布时间】:2016-11-07 09:26:09
【问题描述】:

给定 N、L 和 R,我必须找到 [L,R] 范围内的数字的计数,这些数字可以被 [1,N] 范围内的至少一个素数整除。

约束:

1<=N<=50
1<=L,R<=10^18

例子:

N=5
L=1
R=10

答案 = 8

解释:

[1,5] 范围内的素数是 {2,3,5}。 [1,10] 范围内至少能被 {2,3,5} 中的一个素数整除的数是 {2,3,4,5,6,8,9,10}。

由于约束太高,我的 Python 代码出现“超出时间限制”错误!

我的代码:

import math
def primes_till_n(n):
    sieve=[True]*n
    for i in xrange(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
    return [2]+[i for i in xrange(3,n,2) if sieve[i]]

n,l,r=map(int,raw_input().split())
primes=primes_till_n(n+1)
ct=0
for i in xrange(l,r+1):
    for j in primes:
        if i%j==0:
            ct+=1
            break
print ct

此问题来自 Globalsoft 招聘挑战,Hackerearth,挑战现已结束,未提供社论!

【问题讨论】:

  • 向我们展示您的代码!这是一个挑战吗?如果是,您是否希望我们在不展示您自己尝试的情况下为您解决问题?
  • 能否分享问题链接?只是为了确保这不是一场跑步比赛。
  • 看到这个问题的完全相反的这里:github.com/niklasb/contest-algos/blob/master/… 这是包含-排除原则的基本应用。
  • 您似乎希望我们为您编写一些代码。虽然许多用户愿意为陷入困境的编码人员编写代码,但他们通常只有在发布者已经尝试自己解决问题时才会提供帮助。展示这项工作的一个好方法是包含您迄今为止编写的代码、示例输入(如果有的话)、预期输出以及您实际获得的输出(控制台输出、回溯等)。您提供的详细信息越多,您可能收到的答案就越多。检查FAQHow to Ask
  • 已添加代码。比赛结束,社论不提供!

标签: python algorithm math range primes


【解决方案1】:

让素数数组包含小于 50 的素数。素数数组的大小将是 15。您可以计算区间 [L,R] 中有多少数可以被具有 O(1) 复杂度的数字整除(代码中的 calculateInterval 函数以下)。所以你应该对每个必要的素数做同样的事情。但是您应该执行包含排除以获得正确的结果。复杂度为 O(2^P)。 P 是不大于 N 的素数个数。2^P 最大为 2^15。

    N, L, R, = map(int,raw_input().split())

    def calculateInterval(begin,end,number):
        return (end/number) - ((begin-1)/number)

    primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

    end = 0
    while end < 15:
        if primes[end] > N:
            break
        end += 1

    res = 0
    i = 1
    while i < (1<<end):

        cnt = 0
        num = 1

        for j in xrange(end):
            if (1<<j) & i:
                cnt += 1
                num *= primes[j]

        if cnt%2 == 1:
            res += calculateInterval(L,R,num)
        else:
            res -= calculateInterval(L,R,num)

        i += 1

    print res

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 2021-10-27
    • 2015-09-16
    • 2014-11-05
    相关资源
    最近更新 更多