优化C代码

时间:2013-01-14 15:47:37

标签: c++ c algorithm optimization

假设我们有一个数字数组{1,2,3},我们希望在可能的最少转数中均衡数字;其中“转弯”的定义如下:

转而,您需要按原样修复其中一个元素的值,并将每个其他数字增加1。

考虑到例如。已经提到过 - A = {1,2,3},目标是均衡它们。我已经做过的是制定逻辑,即使用最小转数的方法是选择每回合的最大数量。

  

迭代1:保持A [2] = 3。迭代结束时的数组=> {2,3,3}

     

迭代2:保持A [2] = 3。迭代结束时的数组=> {3,4,3}

     

迭代3:保持A [1] = 4。迭代结束时的数组=> {4,4,4}

所以,轮数= 3

我写的代码如下:

#include<iostream>
#include<stdio.h>

int findMax(int *a,int n)
{
    int i,max;
    max=1;
    for(i=2;i<=n;i++)
    {
        if(a[i]>a[max])
        {
            max=i;
        }     

    }
    return max;
}

int equality(int *a,int n)
{
    int i;
    for(i=1;i<n;i++)
    {
        if(a[i]!=a[i+1]) return 0;
    }
    return 1;
}

int main()
{
    int a[100],i,count,t,posn_max,n,ip=0;
    scanf("%d",&t);
    while(ip<t)
    {
        count=0;
        scanf("%d",&n);

        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        while(equality(a,n)==0)
        {
            posn_max=findMax(a,n);

            for(i=1;i<=n;i++)
            {
                if(i!=posn_max)
                {
                    a[i]=a[i]+1;
                }
            }
            count++;

        }
        printf("%d\n",count);
        ip++;
    }
    return 0;
}

这给了我正确的答案我还需要。但我想进一步优化它。

我的时间限制为1.0秒。但是法官网站告诉我我的代码需要1.01秒。任何人都可以帮助我吗?

据我所知,我使用scanf / printf语句与cout / cin相比,以优化输入/输出部分。但是我还应该做些什么呢?

5 个答案:

答案 0 :(得分:4)

在您的算法中,您将增加期望值中的所有数字。

如果你反过来这样做,减少最大值并留下其余的数字,结果应该是相同的(但内存/数组操作少得多)!

为了使速度更快,您可以完全摆脱内存事件(也由Ivaylo Strandjev建议):找到最小数量和上面的想法(减少数字而不是增加)你知道如何你需要将所有数字减少到这个最小数量。因此,在找到最小值后,您需要一个循环来计算转数。

{1,2,3}

为例
  • 最低为1
  • 转数:(1-1)+(2-1)+(3-1)= 0 + 1 + 2 = 3

如果你真的很聪明,可以在输入数字时直接计算匝数并跟踪当前的最小数量......试试吧! ;)

答案 1 :(得分:2)

您只关心计数,而不关心您需要执行的实际操作。因此,不要逐个执行移动,而是尝试找到一种方法计算移动的数量,而不用执行它们。无论您如何优化它,您编写的代码都不会在时间限制内通过。您所做的最大元素观察将为您提供帮助。

答案 2 :(得分:1)

除了其他评论之外,如果我说得对,你的代码有点太慢,这里有两个优化可以帮助你。

首先,你可以结合使用equality()和findMax(),只扫描一次数组而不是当前最坏的情况(两次)。

其次,您可以将“增加”循环分成两部分(在最大位置的下方和上方)。这将消除检查循环中位置的努力。

答案 3 :(得分:0)

1)尝试展开循环 2)你能用SIMD指令吗?那真的会加速这段代码

答案 4 :(得分:0)

我会printf在一个单独的线程中,因为它是一个I / O操作,并且比你的计算慢得多。

它也不要求复杂的管理,例如Producer-Consumer队列,因为您只将有序数字从0传递到最后count

这是伪代码:

    volatile int m_count = 0;
    volatile bool isExit = false;

    void ParallelPrint()
    {
        int currCount = 0;

        while (!isExit)
        {
            while (currCount < m_count)
            {
                currCount++;
                printf("%d\n", currCount);
            }

            Sleep(0); // just content switch
        }
    }

scanf("%d",&t);之前打开线程(我猜这个初始化时间不计算在内),并在isExit = true;返回之前按Main()关闭帖子。

相关问题