POJ-3978-Primes

Primes
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4450   Accepted: 1666

Description

A pretty straight forward task, calculate the number of primes between 2 integers. 

Given 2 integers A ≤ B < 105 what’s the number of primes in range from A to B inclusive. 

Note: A prime number is a positive integer greater than 1 and is divisible by 1 and itself only. For N to be prime it is enough to test the divisibility of numbers less than or equal to square root of N.

Input

As many as 1000 lines, each line contains 2 integers A and B separated by a space. Input is terminated when A = B = -1 (Do not process this line).

Output

For every line in input – except for the last line where A = B = -1 - print the number of prime numbers between A and B inclusive.

Sample Input

0 9999
1 5
-1 -1

Sample Output

1229
3

Source

 
问题分析:
该问题比较简单直接,要求我们算出a-b之间一共有多少个素数。
input size是10^5,time limit只有1s
很明显用循环从2-sqrt(i)一个一个的去判断是不行的,会出现超时的结果。
 
所以在算法的选取上要选择筛法去求素数,算法分复杂度是一个o(n)的复杂度。
 
算法分析:
筛法,顾名思义就是用一个筛子将不是不满足条件的数字筛掉,同时用一个容器装下没有被筛出去的数字
 
那么这道题的筛子是什么呢?
我们知道,素数是只能被1和自己整除的数,那恰恰相反,合数就可以被其他数所整除,我们就可以以这个条件作为筛子,慢慢的筛掉合数。
 
我们注意到如果一个合数x=a*b,那么其中必有一个小于sqrt(x),所以我们将所有小于sqrt(x)的所有素数记录下来,根据题目要求记录下1000以内的所有素数
就已经绰绰有余了。然后筛掉所有的这些素数的倍数就大功告成了。
 
ac代码:
 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 int prime[1000]={0};//记录下1000以内的素数,若为0则为素数,为1则为合数
 5 int record[100000+1]={0};//记录下100000以内所有素数,若为0则为素数,为1则为合数
 6 int main()
 7 {
 8         record[0]=1;
 9         record[1]=1;
10         int a,b;
11         int  i,j;
12         for(i=2;i<1000;i++)
13         {
14                 double t=i;
15                 for(j=2;j<=sqrt(t);j++)
16                 {
17                         if(i%j==0)
18                         {
19                                 prime[i]=1;
20                                 break;
21                         }
22                 }
23         }
24            for(i=2;i<=(int)sqrt(100000.0);i++)
25         {
26                 if(prime[i]==0)
27                 {
28                         for(j=i*i;j<=100000;j++)//j从i*i开始循环,因为i*i以前的数字已经被比j小的数字筛掉了,如5从25开始,然而15已经被3筛掉了
29                         {
30                                 if(j%i==0)record[j]=1;
31                         }
32                 }
33         }
34         while(cin>>a>>b)
35         {
36                 if(a==-1&&b==-1)break;
37                 int sum=0;
38                 for(i=a;i<=b;i++)
39                 {
40                         if(record[i]==0) sum++;
41                 }
42                 cout<<sum<<endl;
43         }
44         return 0;
45 }

 

posted @ 2018-08-05 14:05  记得每天写代码  阅读(149)  评论(0编辑  收藏  举报