Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 根据需要拆分自然数数组_Arrays_Numbers - Fatal编程技术网

Arrays 根据需要拆分自然数数组

Arrays 根据需要拆分自然数数组,arrays,numbers,Arrays,Numbers,我有两个自然数数组{Ai}和{Bi}。所有元素的和都相等 我需要将两个数组中的每个元素拆分为三个自然数: Ai=A1i+A2i+A3i Bi=B1i+B2i+B3i 这样,A1的所有元素之和等于B1的所有元素之和,并且对于所有其他对而言相同 我最初忘记的重要部分是: A1j、A2j、A3j中的每个元件应介于Aj/3-2和Aj/3+2之间,或至少等于这些数字中的一个 B1j、B2j、B3j中的每个元素应介于Bj/3-2和Bj/3+2之间,或至少等于这些数字中的一个 所以数组的元素必须分成几乎相等的

我有两个自然数数组
{Ai}
{Bi}
。所有元素的和都相等

我需要将两个数组中的每个元素拆分为三个自然数:

Ai=A1i+A2i+A3i
Bi=B1i+B2i+B3i

这样,A1的所有元素之和等于B1的所有元素之和,并且对于所有其他对而言相同

我最初忘记的重要部分是:

A1j、A2j、A3j中的每个元件应介于Aj/3-2和Aj/3+2之间,或至少等于这些数字中的一个

B1j、B2j、B3j中的每个元素应介于Bj/3-2和Bj/3+2之间,或至少等于这些数字中的一个

所以数组的元素必须分成几乎相等的部分


我在寻找一些更优雅的解决方案,而不仅仅是计算两个阵列的所有可能变量。

您应该查找

在这种情况下,它似乎与一些类似

对于查找A1_i、A2_i、A3_i,您应该递归执行:

def find_numbers(n, a, arr):
    if arr[n] not empty:
        return

    if n == 0:
        arr[n].append(a)
        return

    if a.size() > 2:
        return 
    t = n

    for each element of a:
        t -= element

    for i = 0 to :
         find_numbers(n, append(a, i), arr)
我们使用
arr
,这样我们就不需要为每个数字计算可能的组合的多次。如果在一段时间后查看调用树,此函数将返回来自
arr
的组合,而不会再次计算它们。 在您的主要通话中:

arr = []
for each n in A:
    find_number(n, [], arr)
for each n in B:
    find_number(n, [], arr)
现在您有了arr[n]中每个n的所有组合。
我知道这是问题的一个子部分,但从arr中为每个a_I,B_I找到正确的组合与此非常相似阅读我给你的链接非常重要,这样你就可以理解背后的基本理论。

你应该查一下基本原理

在这种情况下,它似乎与一些类似

对于查找A1_i、A2_i、A3_i,您应该递归执行:

def find_numbers(n, a, arr):
    if arr[n] not empty:
        return

    if n == 0:
        arr[n].append(a)
        return

    if a.size() > 2:
        return 
    t = n

    for each element of a:
        t -= element

    for i = 0 to :
         find_numbers(n, append(a, i), arr)
我们使用
arr
,这样我们就不需要为每个数字计算可能的组合的多次。如果在一段时间后查看调用树,此函数将返回来自
arr
的组合,而不会再次计算它们。 在您的主要通话中:

arr = []
for each n in A:
    find_number(n, [], arr)
for each n in B:
    find_number(n, [], arr)
现在您有了arr[n]中每个n的所有组合。 我知道这是问题的一个子部分,但从arr中为每个a_I,B_I找到正确的组合与此非常相似阅读我给你的链接非常重要,这样你才能理解背后的基本理论

我寻找一些更优雅的解决方案,而不仅仅是计算两个数组的所有可能变量

应该可以将它们分开,使A1、A2和A3的总和接近a的三分之一,而B的总和相同。只需将所有值精确设为三分之一就很容易了,但对于自然数来说这是不可能的。因此,我们必须
floor
results(琐碎的)并将余数均匀地分布在三个数组上(可管理的)

我不知道这是否是唯一的解决方案,但它在
O(n)
中有效,我的直觉告诉我它将保存你的不变量(尽管我没有证明它):

我们也可以在不进行分割的情况下形成回路,仅将A[i]的单个单元(1)分布在A[x][i]上:

n = 3
for j=0 to n
    A[j] = {}
    for k=0 to |A|
        A[j][i] = 0
x = 0 // rotating pointer for the next subarray
for i in A
    // distribute the rest over the arrays, and rotate the pointer
    for j=0 to A[i]
        A[x][i]++
        x++
我寻找一些更优雅的解决方案,而不仅仅是计算两个数组的所有可能变量

应该可以将它们分开,使A1、A2和A3的总和接近a的三分之一,而B的总和相同。只需将所有值精确设为三分之一就很容易了,但对于自然数来说这是不可能的。因此,我们必须
floor
results(琐碎的)并将余数均匀地分布在三个数组上(可管理的)

我不知道这是否是唯一的解决方案,但它在
O(n)
中有效,我的直觉告诉我它将保存你的不变量(尽管我没有证明它):

我们也可以在不进行分割的情况下形成回路,仅将A[i]的单个单元(1)分布在A[x][i]上:

n = 3
for j=0 to n
    A[j] = {}
    for k=0 to |A|
        A[j][i] = 0
x = 0 // rotating pointer for the next subarray
for i in A
    // distribute the rest over the arrays, and rotate the pointer
    for j=0 to A[i]
        A[x][i]++
        x++

我增加了一项规定,即A1、A2和A3必须在不知道B的情况下从A计算,同样,B1、B2和B3必须在不知道A的情况下计算

要求每个A1i、A2i、A3i必须在[Ai/3–2,Ai/3+2]中,这意味着A1、A2和A3元素的总和必须分别约为A元素的三分之一。该规定迫使我们对其进行完全定义

我们将以任意顺序构造数组(例如,从元素0到最后一个元素)。在这样做时,我们将确保阵列保持几乎平衡

设x是要处理的A的下一个元素。设a为圆形(x/3)。为了计算x,我们必须在数组A1、A2和A3中加上总共3•a+r,其中r是–1、0或+1

设d为和(A1)–和(A)/3,其中和是迄今为止处理的元素。最初,d是零,因为没有处理任何元素。根据设计,我们将确保每个步骤的d为–2/3、0或+2/3

分别向A1、A2和A3追加三个值,如下所示:

  • 如果r为-1,d为-2/3,则附加a+1、a-1、a-1。这将d更改为+2/3
  • 如果r为-1,d为0,则附加a-1、a、a。这将d更改为–2/3
  • 如果r为-1,d为+2/3,则附加a-1、a、a。这会将d更改为0
  • 如果r为0,则追加a、a、a。这使d保持不变
  • 如果r为+1,d为–2/3,则附加a+1、a、a。这会将d更改为0
  • 如果r为+1,d为0,则附加a+1、a、a。这将d更改为+2/3
  • 如果r为+1,d为+2/3,则附加-1、a+1、a+1。这将d更改为–2/3
最后,A1、A2和A3之和由模三之和唯一确定。A1的和是(和(A3)-2)/3、和(A3)/3或(和(A3)+2)/3,这取决于模三的和是否分别与-1、0或+1全等


完成演示:

在任何情况下,都会将–1、a或+1追加到数组中。a是圆形的(x/3),因此它与x/3的区别在于