【问题标题】:sum of all arr[j] where i divides ji 除 j 的所有 arr[j] 的总和
【发布时间】:2016-09-15 14:03:40
【问题描述】:

找到索引可被 i 整除且复杂度最低的数组所有元素的总和的最佳方法是什么。

我写了下面的代码。但那是蛮力。我能做得更好吗

#include<stdio.h>

int main() {
    int n, q;
    int mod = 1000000000 + 7;
    scanf("%d", &n);

    int arr[n+1];
    int i;
    for (i = 1; i <= n ; ++i) {
        scanf("%d", &arr[i]);
    }

    int p;
    scanf("%d", &p);
    int sum = 0;
    int j;
    for(j  = p; j <= n; j = j+p) {
        sum = (sum + arr[j]) % mod;
    } 
    printf("%d\n",sum);
    return 0;
}

【问题讨论】:

  • 你必须检查数组的所有元素,所以你不能比 O(n) 更好。
  • 好吧,您已经发布了 C 代码……但如果您认为它不适用于特定语言,您可以将其标记为“与语言无关”。
  • 在使用普通 int 时除以 10 亿?这段代码有问题,你确定没有整数溢出吗?
  • @AndyTurner - 你对复杂度为 O(n) 是正确的,但对数组的“check all 元素是错误的”。请参阅 OP 的代码,其中他仅检查索引为 p 倍数的元素。
  • 发布的目标不包含% mod的原因。发布为什么代码需要做% mod,否则只需删除% 以提高性能。

标签: c arrays language-agnostic


【解决方案1】:

您说您的示例实现是“蛮力”,并询问您是否可以“做得更好”。蛮力通常意味着一种易于实现的方法,但执行的工作量或使用的内存量比理论上需要的量要多得多。它建议投入大量资源来代替有效的运营。通常,“明显更多”归结为此类方法具有比最佳方法更高的渐近复杂度。

您的示例实现不是那样的。添加n / p 任意数字需要n / p 操作,因此O(n) 是该任务的算法可以具有的最小渐近复杂度。那是你的实现的渐近复杂度,所以在这个意义上它不能被改进。

此外,您的实现似乎执行的总体操作与您希望的一样少。考虑一下求和循环的这种简单、替代、更糟糕的实现:

    for(j = 1; j <= n; j++) {
        if (j % p == 0) {
            sum = (sum + arr[j]) % mod;
        }
    } 

这可以被视为将需求更直接地转换为 C 代码。虽然它仍然只有 O(n),但它可能被合理地描述为蛮力实现,因为 (p-1) 倍的增量超过了 jn 的计算 j % p,这两者你的实现避免了。

底线:不,没有比您介绍的实施方式更有效的实施方式了。

【讨论】:

    猜你喜欢
    • 2012-10-20
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多