如何降低此代码的复杂性(如下所示)?

时间:2016-09-13 12:29:29

标签: c algorithm

问题陈述:  找出N之下所有3或5的倍数之和。

输入格式: 第一行包含表示测试用例数的T.接下来是T行,每行包含一个整数N。

约束:

1 <= T <= 10 ^ 5

1 <= N <= 10 ^ 9

输出格式: 对于每个测试用例,打印一个整数,表示N的所有倍数为3或5的总和。

这是我的代码:

#include <stdio.h>

int main() {
    long t,i,x;
    scanf("%ld",&t);
    long y[t];
    for(i=0; i<t; i++) {
        scanf("%ld",&x);
        long j,k,sum= 0;
        if(x<=3)
            sum= 0;
        else if(x<=5)
            sum= 3;
        else {
            for(j=3; j<x; j+=3)
                sum= sum + j;
            for(j=5; j<x; j+=5)
                if(j%3!=0)
                  sum = sum + j;
        }   
        y[i] = sum;
    }   
    for(i=0; i<t; i++) {
        printf("%ld\n",y[i]);
    }
    return 0;
}    

2 个答案:

答案 0 :(得分:1)

有一个时间复杂度为O(T)的解决方案:

使用公式求整数1+2+3+...+n = n*(n+1)/2

另请注意3+6+9+...+(3*n) = 3*(1+2+3+...+n) = 3*n*(n+1)/2

计算出有多少可被3整除的数字。计算他们的总和。

计算出有多少可被5整除的数字。计算他们的总和。

计算出有多少可被15整除的数字(= 3 * 5)。计算他们的总和。

总和为sum3 + sum5 - sum15。被3和5整除的数字(因此是15)都是sum3和sum5,所以除非我们减去sum15,否则它们将被计算两次。

请注意,总和将溢出32位整数,因此请确保使用64位整数类型。

答案 1 :(得分:0)

如果你使用古代数学力量,你可以实现不变的复杂性。

首先弄清楚有多少可被3整除的数字 计算他们的总和 (你不需要任何循环,你只需要基本算术。)

重复五次和十五次。

总数是一个涉及这三个总和的简单表达式。

详细信息留给读者练习。