这是我对问题陈述http://www.spoj.com/problems/ABSP1/的处理方法 - 请检查我的代码是否有任何转角,因为根据我的测试用例,它给出了正确答案。
问题陈述:
您将以非递减顺序给出N个数字的数组。你有 回答所有不同的绝对差异的总和 在给定数组中对。
的scanf("%d",&安培; TotalElements);
for(i=0;i<TotalElements;i++)
scanf("%d",&Array[i]);
FirstSum=TotalSum=0;
for(i=0;i<TotalElements;i++)
FirstSum+=abs(Array[i]-Array[0]);
TotalSum=FirstSum;
SumTillNow=Array[0];
for(i=1;i<TotalElements;i++){
Difference=Array[i]-Array[0];
NextSum=FirstSum-Difference*(TotalElements-i)-SumTillNow+(i)*Array[0];
TotalSum+=NextSum;
SumTillNow+=Array[i];
}
printf("%lld\n",TotalSum);
答案 0 :(得分:2)
据我所知,你的逻辑很好。 我认为错误答案可能与您使用的变量类型有关。
让我们密切关注您的代码中的这句话。
NextSum=FirstSum-Difference*(TotalElements-i)-SumTillNow+(i)*Array[0];
Here FirstSum = summation( A[k] - A[0] ) for all k > 0
= summation( A[k] ) - N*A[0]
Difference = A[i] - A[0].
因此声明变为:
NextSum = summation( A[k] ) - N*A[0] - (A[i] - A[0])*(N-i) - summation( A[j] ){j<i} + i*A[0]
= summation( A[m] ){m >= i} - A[i]*(N-i)
此总和考虑了A[i]
和A[m]
m > i
之间的所有绝对差异。这应该给你正确的答案。
此外,还有一种更简单的方法来执行求和。我把它包括在内是为了完整。
如果你看一下每个A [i]出现在绝对差值之和中的次数,
&#34; -A [0]&#34;将出现N-1次
&#34; -A [1]&#34;将出现N-2次,A [1]将出现1次。因此净效应为(1 - (N-2))*A[1]
。
同样地,第[i]个术语应为(i - (N-i-1))*A[i]
= (2i + 1 - N)*A[i]
。
您可以相应地计算系列。
答案 1 :(得分:1)
问题设定者似乎没有足够的经验。原因如下:
他说不同的对,但看起来不像。也许他的意思是UNORDERED对。
测试数据不符合约束条件。断言输入数据验证了这一点。使用64位有符号整数进行输入。
对程序进行更改时请牢记这两点(特别是第2点)并且应该接受它。
答案 2 :(得分:0)
有一件事情会浮现在脑海中。 SPOJ说:
Do you know what distinct pair means? Suppose you have an array of 3 elements: 3 5 6
Then all the distinct pairs are:
3 5
3 6
5 6
如果您使用3个元素的数组:3 3 4那么您有多少个不同的对子?类似地:3 3 3. SPOJ没有准确地阐明不同的对是什么,但我假设两对a1 a2和b1 b2仅在a1&lt;&gt;时是不同的。 a2或b1&lt; B2。如果是这种情况,那么您将需要过滤掉数组中的所有重复项。