找到总和为k的倍数的对

时间:2013-09-12 00:35:40

标签: algorithm

假设我有一组N(N <= 10 ^ 10)个自然数。其中,我希望形成2个数字的集合,使得它们的总和可以被k整除。假设N=4,即数字:1, 2, 3, 4k=2。因此,形成的集合将是:: (1,3)(2,4)

不重复,集合的第一个元素应小于第二个元素。

以下是我的代码和逻辑。但我不知道为什么它给N的lage值提供了错误的答案:

int c[] = new int[K];
for (long j=1;j<=N;j++) {
    ++c[(int)j%K];//storing remainder in array
}
long count = 0; 
if (K%2==0)
    count = (c[0]*(c[0]-1) + c[K/2]*(c[K/2]-1))/2;//modulus that have value 0 or half of k, should be paired together, in C(N,2) ways.
else
    count = c[0]*(c[0]-1)/2;
for (int j=1;j<(K+1)/2;j++) {
    count+=c[j]*c[K-j];//sets whose modulus form a sum of K
}

1 个答案:

答案 0 :(得分:1)

我至少看到两件事:

首先,在这一行:

++c[(int)j%K];//storing remainder in array

我非常确定在实际执行int操作之前会对%进行强制转换(但不是100%肯定)。

其次,在代码的其余部分中,对于所有count = ...行,您正在对int进行算术运算,然后将结果分配给long。在算术操作完成之后,隐式转换为long。因此,如果操作溢出int,您最终会溢出然后转换为long

如果你想解决这个问题,你必须在右侧明确地对long进行强制转换,以确保没有任何算术运算在两个int上运行。 (虽然除非你有内存限制,否则最好只使用long s而不是int s,jK除外