【问题标题】:increase speed efficiency of the code提高代码的速度效率
【发布时间】:2017-07-13 11:24:37
【问题描述】:
// author- squeamishossifrage
#include <stdio.h>

int main() {
    int k, t, A, N, B, max, num_tests;
    scanf("%d", &num_tests);
    while (num_tests--) {
        scanf("%d %d", &N, &B);
        A = 1;
        k = N / B;
        for (k=N/B,max=0; k>0; k--) {
            t = (N-k*B) * k;
            if (t > max) max = t;
        }
        printf("%d\n", max);
    }
    return 0;
}

上面的代码(取自this answer)似乎需要一秒钟多一点,但约束是在一秒钟内执行。我们如何在不使用多线程的情况下提高这种代码的速度(我不知道如何使用它们)?

【问题讨论】:

  • 不是说这会有帮助,但为什么是k = N / B;,然后是for (k=N/B,...
  • 您很可能需要更高效的算法。 (如果你从一个低效的算法开始,你做了多少代码优化都没关系 - 代码仍然很慢。)
  • 如果你告诉我们算法应该做什么会更容易吗?
  • 这可能应该在 Code Review 上问,而不是 SO。
  • 闻起来像 Project Euler 挑战。

标签: c performance optimization


【解决方案1】:

这应该可以解决问题:

#include <stdio.h>

int main() {
    int k, N, B, max, num_tests;
    scanf("%d", &num_tests);
    while (num_tests--) {
        scanf("%d %d", &N, &B);
        k = (double)N / (2*B)+0.5;
        max = (N-k*B)*k;
        printf("%d\n", max);
    }
    return 0;
}

如果没有循环,应该会更有效率。这个概念是用代数方式解决问题,然后适当地四舍五入。

最大k的

t = N*k - k²*B

可以通过对k微分得到:

k = N/(2*B)

这必须适当地四舍五入,然后插入到原始方程中

t = (N-k*B) * k;

那么这是正确的(最大)解决方案。

【讨论】:

    【解决方案2】:

    函数:printf() 和函数:scanf() 非常“繁重”,需要很多 CPU 周期。

    强烈建议使用getchar_unlocked()putchar_unlocked(),因为它们更快。

    这里有两个比 printf()scanf() 快得多的 I/O 函数,注意使用 size_t 而不是 int

    #include <stdio.h>
    
    void fastRead( size_t *a );
    void fastWrite( size_t a );
    
    inline void fastRead(size_t *a)
    {
        int c=0;
        // note: 32 is space character
        while (c<33) c=getchar_unlocked();
    
        // initialize result value
        *a=0;
    
        // punctuation parens, etc are show stoppers
        while (c>47 && c<58)
        {
            *a = (*a)*10 + (size_t)(c-48);
            c=getchar_unlocked();
        }
        //printf( "%s, value: %lu\n", __func__, *a );
    } // end function: fastRead
    
    
    inline void fastWrite(size_t a)
    {
        char snum[20];
        //printf( "%s, %lu\n", __func__, a );
    
        int i=0;
        do
        {
            // 48 is numeric character 0
            snum[i++] = (char)((a%10)+(size_t)48);
            a=a/10;
        }while(a>0);
    
        i=i-1; // correction for overincrement from prior 'while' loop
    
        while(i>=0)
        {
            putchar_unlocked(snum[i--]);
        }
        putchar_unlocked('\n');
    } // end function: fastWrite
    

    【讨论】:

      猜你喜欢
      • 2015-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多