假设我有一组N
(N <= 10 ^ 10)个自然数。其中,我希望形成2个数字的集合,使得它们的总和可以被k
整除。假设N=4
,即数字:1, 2, 3, 4
和k=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
}
答案 0 :(得分:1)
我至少看到两件事:
首先,在这一行:
++c[(int)j%K];//storing remainder in array
我非常确定在实际执行int
操作之前会对%
进行强制转换(但不是100%肯定)。
其次,在代码的其余部分中,对于所有count = ...
行,您正在对int
进行算术运算,然后将结果分配给long
。在算术操作完成之后,隐式转换为long
。因此,如果操作溢出int
,您最终会溢出然后转换为long
。
如果你想解决这个问题,你必须在右侧明确地对long
进行强制转换,以确保没有任何算术运算在两个int
上运行。 (虽然除非你有内存限制,否则最好只使用long
s而不是int
s,j
和K
除外}