有没有办法改善这个程序的运行时间?我从在线评判中获得超出时间限制的错误,似乎我的程序运行缓慢? 所以,这是该计划的问题:http://www.spoj.com/problems/PRIME1/
我的代码(语言c):
#include <stdio.h>
void FindPrime (int m, int n)
{
int i, prime = 1;
if (m <= n)
{
for (i = m - 1; i > 1; i--)
{
if (m % i == 0)
{
prime = 0;
break;
}
}
if (prime == 1 && m != 1)
printf ("%d\n", m);
FindPrime (m + 1, n);
}
}
int main ()
{
int num1, num2, i, cases;
scanf ("%d", &cases);
while (cases != 0)
{
scanf ("%d %d", &num1, &num2);
FindPrime (num1, num2);
printf ("\n");
cases--;
}
return 0;
}
答案 0 :(得分:0)
要解决这个问题,您需要学习“Eratosthenes的筛子”。
首先,从here了解它的工作原理。但是,这还不足以解决这个问题。因为,算法的复杂性是O(n.log(log(n)))。因此,如果我们把 n = 1000000000 。它肯定无法执行。
现在,时间来优化它。从here阅读。但是,我们已经完成了。
(完成上述两项后请阅读本节)因为我们要找到素数是 [m,n] 的范围。因此,首先使用Eratosthenes( sqrt(10 ^ 9)= 31622.7 的筛子,在2到32000的范围内创建一个素数列表(让我们称之为 primeList ),这小于32000)。现在,检查 [m,n]
范围内的每个数字 k3.1。如果数字 k 在 2-32000 的范围内,则该数字位于 primeList 中。打印出来。
3.2。如果数字 k &gt; 32000,并且不可被&lt; = sqrt(k)以及 primeList 中的所有数字整除。打印出来。否则,忽略或不打印它。 (记住它'1'不是素数)。
您可以查看我的solution。但是,虽然所应用的概念是相同的,但它的实现与我解释的略有不同。
答案 1 :(得分:0)
你的代码计算/列出数字m和amp之间的素数。 n个案例次数。现在你的算法花费O(n)时间用于m&amp;的每个值。因此,您的代码对单个案例所花费的总时间是O(nxm)或O(n ^ 2)倍。总共花费的时间是* O(n ^ 2)..这很糟糕。使用一些更好的算法,以减轻复杂性.. 检查此 Sieve of Eratosthenes
的修改版本#include <stdio.h>
#define SIZE (int)(sizeof(boolean) / sizeof(int))
int main(){
int up,low;
int i,j;
printf("\nEnter the upper limit: ");
scanf("%d", &up);
printf("\nEnter the lower limit: ");
scanf("%d", &low);
int boolean[up];
int list[up];
for(i = 0; i < SIZE; i++){
boolean[i] = 1;
list[i] = 2 + i;
}
for(i = 0; i <= up; i++){
if (boolean[i] == 1)
for(j = i +1; j < SIZE; j++)
if(list[j] % list[i] == 0)
boolean[j] = 0;
}
for(i = 0; i < SIZE; i++)
if(boolean[i] == 1 && list[i] >= low && list[i] <= up)
printf("%d ", list[i]);
printf("\n");
return 0;
}
这不会多次访问一个号码。因此会降低对数刻度的复杂性。