当前位置: 首页 > 知识库问答 >
问题:

小于或等于N的两个数对的计数数,使该对数的位数之和为素数

越昊穹
2023-03-14
    null

我可以想到蛮力方法。其中我需要放两个从1到N的循环,计算每个x和y对的数字和,并检查它是否是素数。但它不是一个最优解,因为N的范围为10^50。

共有1个答案

慕璞
2023-03-14

我一直在尝试这个问题--我花了几次努力才明白这个问题。我想在放弃之前把我学到的东西写下来,然后转向更容易的事情!

首先,我对@Shiva解决方案的返工,它能更快地产生正确的输出:

import sys
from functools import lru_cache

def sum_of_digits(number):
    summation = 0

    while number > 0:
        summation += number % 10
        number //= 10

    return summation

@lru_cache()
def is_prime(number):
    if number < 2:
        return False

    if number % 2 == 0:
        return number == 2

    divisor = 3

    while divisor * divisor <= number:
        if number % divisor == 0:
            return False
        divisor += 2

    return True

maximum = int(sys.argv[1])

count = 0

for i in range(maximum + 1):
    sum_i = sum_of_digits(i)

    for j in range(i, maximum + 1):
        if is_prime(sum_i + sum_of_digits(j)):
            count += 1

print(count)

我在下面用这个作为速度和准确性的基准。

import sys
from math import ceil
from collections import defaultdict

VERBOSE = False

def sum_of_digits(number):
    summation = 0

    while number:
        summation += number % 10
        number //= 10

    return summation

def sieve_primes(n): 
    sieve = [False, False] + [True] * (n - 1)

    divisor = 2

    while divisor * divisor <= n: 
        if sieve[divisor]: 
            for i in range(divisor * divisor, n + 1, divisor): 
                sieve[i] = False
        divisor += 1

    return [number for number in range(2, n + 1) if sieve[number]]

power = int(sys.argv[1])  # testing up to 10 ** power

maximum_sum_of_digits = 18 * power
primes_subset = sieve_primes(maximum_sum_of_digits)

sums_of_digits = defaultdict(int)
for i in range(10 ** power + 1):
    sums_of_digits[sum_of_digits(i)] += 1

if VERBOSE:
    print('maximum sum of digits:', maximum_sum_of_digits)
    print('maximum prime:', primes_subset[-1])
    print('number of primes:', len(primes_subset))
    print('digit sums cached', len(sums_of_digits))

primes_subset = set(primes_subset)

count = 0

for i in sums_of_digits:
    sum_i = sums_of_digits[i]

    for j in sums_of_digits:
        if i + j in primes_subset:
            count += sum_i * sums_of_digits[j]

print(ceil((count + 2) / 2))  # hack to help adjust between duples and no duples count; sigh
        @Shiva reworked            My Attempt
          exact    secs        approx    secs
10^1         24    0.03            24    0.03
10^2       1544    0.04          1544    0.04
10^3     125030    0.49        125029    0.04
10^4   12396120   51.98      12396119    0.05
10^5 1186605815 6223.28    1186605813    0.14
10^6                     113305753201    1.15
10^7                   11465095351914   12.36
10^8                 1120740901676507  137.37
10^9               105887235290733264 1626.87
 类似资料:
  • 问题是要找出A和B(包括A和B)之间的数字总数等于S。 同时打印A和B(含)之间的最小数字。 输入: 由A、B、S组成的单线。 输出: 两行。 在第一行中,A和B之间的整数数,其位数之和等于S。 在第二行中,A和B之间的最小数字。 约束: 1. 1. 来源:黑客地球 我的解决方案只适用于30%的输入。对此最好的解决方案是什么? 我现在使用的算法计算最小数字的和,然后在十位数的每次更改后再次计算和。

  • 我有一个大小为的整数值数组和一个给定的。 我想找到子序列的总数,使得每个子序列的元素总和小于。例如:设 ,,数组的元素为 ,则其总子序列为 作为- 但是,所需的子序列是: 也就是说,不被取,因为它的元素和是,这大于,即

  • 问题内容: 如果我有一个PHP数组: 带有值: 我有一个变量: 如何返回值?: 因为那是数组中最接近38(递增)的值? 问候, 泰勒 问题答案:

  • 我想找到给定正整数数组中元素的最大数目,使得它们的和小于或等于给定的k。例如,我有一个数组 答案是3,因为1,2,3是求和6的最大元素。

  • 给定一个数组形式的未排序(多)整数集,求其和大于或等于常量整数x的最小基数子集。 我们的集合是{4 5 8 10 10},x=15,所以最小基数子集和 这个问题与以下问题相关但不同:给定一个n个整数的列表,找到大于X的最小子集和在前面的问题中,作者要求得到一个和最接近X的子集,这里我们想要任何子集

  • 假设您希望在排序数组中查找值1的第一个匹配项。对于小数组(二进制搜索之类的东西没有回报),您可以通过简单地计算小于该值的值的数量来实现这一点:结果就是您要查找的索引。 在x86中,您可以使用(加进位)来实现该方法的高效无分支2实现(中的起始指针中的长度和要在中搜索的值): 答案以rax结束。如果你展开它(或者如果你有一个固定的、已知的输入大小),只有cmp;adc指令对被重复,因此每次比较的开销接