如何减少运行时间?

时间:2015-03-28 19:34:36

标签: c algorithm primes number-theory

以下是我正在尝试解决的问题的链接:http://acm.timus.ru/problem.aspx?space=1&num=1086

这是我的方法:

#include <stdio.h>
#include <math.h>

int main()
{
    int n, i, m, p;

    scanf("%d", &n);

    for(i = 0; i < n; i++)
    {
        scanf("%d", &m);

        p = find_prime(m);
        printf("%d\n", p);
    }

    return 0;
}

int find_prime(int a)
{
    int i, p = 1, t, prime[15000], j;
    prime[0] = 2;

    for(i = 0; i < a; )
    {
        if(p == 2)
        {
            p++;
        }else
        {
            p = p + 1;
        }
        t = 0;
        for(j = 0; prime[j] <= sqrt(p); j++)
        {
            if(p%prime[j] == 0 && p != 2)
            {
                t = 1;
                break;
            }
        }
        if(t != 1)
        {
            i++;
            prime[i] = p;
        }
    }

    return p;
}

我知道算法很好,它会产生正确的答案。但我总是得到“超出时间限制”。我无法将运行时下载到2秒。它总是等于2.031秒。我尝试过其他一些方法,例如,我遍历所有数字,直到找到第m个素数,我试图跳过大于2的偶数整数,但我仍然得到2.031秒。

我该怎么办?

3 个答案:

答案 0 :(得分:3)

您的素数缓冲区不一定是每次都重新计算的局部变量。

您可以通过将缓冲区存储在全局范围内并使用全局计数器来跟踪到目前为止已计算的素数以及请求的最大数量,来尝试memoize

如果您要求的下一个号码小于之前的最大号码,则应该回退到相应的预先计算的号码。如果下一个数字大于之前的最大值,请将其设为新的最大值 - 并尝试从上次停止的位置开始计算。

答案 1 :(得分:1)

删除

  if(p == 2)
    {
        p++;
    }else
    {
        p = p + 1;
    }

并将其替换为

p++

答案 2 :(得分:0)

据我了解,

问题是找到下一个素数大于所有先前输入数字的总和。

这意味着有一些期望。

1) the sum of the prior input numbers is available in find_prime(). 
2) for simplification, the last found prime number is available in find_prime().  

这些期望都没有实现。

然后在find_prime()中堆栈上有6万字节数组。

建议将其移动到文件全局位置并包含“静态”修改器。

将先前的输入总和移动到文件全局位置,因此它始终可用。

了解整体速度,

首先计算数组中的所有素数,从而用数值填充数组。那么

1) add new input to sum, 
2) index into array using sum. 
3) return value found in array.