找出总和可被k整除的对数?

时间:2013-09-12 16:19:05

标签: numbers combinations combinatorics

给出k的值。这样k <= 100000 我们必须打印对的数量,使得每对元素的总和可被k整除。 在以下条件下,第一个元素应小于第二个元素,且两个元素应小于10 9

4 个答案:

答案 0 :(得分:2)

我找到了一个解决方案,让ab数字(a+b)%k=0,然后我们必须找到(a,b)对,其中a<b,所以让我们计算(a,b)满足条件a+b=k的次数,例如,如果k=3 0+3=3, 1+2=3, 2+1=3, 3+0=3有4对但只有2对(K+1)/2 (integer division)那么类似用于查找总和为(a,b)的对2k, 3k,.. nk,解决方案为(k+1)/2 + (2k+1)/2 + (3k+1)/2 + ... + (nk+1)/2,等于时间复杂度为(k*n*(n+1)/2 + n)/2的{​​{1}},请注意O(1),因为n*k=2*10^9对于给定的约束不能超过a

答案 1 :(得分:0)

一些伪代码可以帮助您入门。它使用你说你试过的蛮力技术,但你的代码可能有问题吗?

max = 1000000000
numberPairs = 0
for i = 1 to max - 2 do
    for j = i + 1 to max - 1 do
        if (i + j) mod k = 0 then
            numberPairs = numberPairs + 1
        end if
    end do
end do

答案 2 :(得分:0)

一种方式是蛮力:

int numPairs = 0;
for (i = 0; i < 10e9; i++)
{
    for (j = i+1; j < 10e9; j++)
    {
        int sum = i + j;
        if (sum % k == 0) numPairs++;
    }
 }
 return numPairs;

我会留给你优化它以提高性能。我至少可以想到一种显着提高速度的方法。

答案 3 :(得分:0)

使用哈希图解决O(N)时间和O(N)空间中的问题。

概念如下:

If (a+b)%k=0 where

a=k*SOME_CONSTANT_1+REMAINDER_1 

b=k*SOME_CONSTANT_2+REMAINDER_2

then (REMAINDER_1 +REMAINDER_2 )%k will surely be 0

因此对于一个数组(4,2,3,31,14,16,8),如果您有如下所示的信息,则k = 5,您可以找出所有对的总和%k = 0

enter image description here

请注意,最底部的行包括从0到k-1的所有余数以及与之对应的所有数字。 现在,您需要做的就是将两个指针彼此相对移动,直到它们碰面。如果两个指针位置都有与之关联的数字,则它们的总和%k将为0

要解决此问题,您可以使用哈希表来跟踪到目前为止所看到的所有剩余部分

  1. 创建一个哈希映射Map
  2. 用0到k-1预先填充其键;
  3. 遍历数组,并使用Key =剩下的数将每个数字的剩余数放在映射中,然后将实际的数字放入列表中,
  4. 使用两个相互移动的指针遍历键集。还有sum += listSizeAsPointedByPointer1 * listSizeAsPointedByPointer2