toj 4088 and toj 4090 筛素数

4088:

题意:判断闭区间a到b之间内的素数个数是否为素数。

思路:筛吧。

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int N = 10001;
 6 bool prime[N];
 7 int cnt[N];
 8 
 9 void get()
10 {
11     memset( prime, true, sizeof(prime) );
12     prime[0] = prime[1] = false;
13     for ( int i = 2; ; i++ )
14     {
15         int j = i * i;
16         if ( j >= N ) break;
17         do
18         {
19             prime[j] = false;
20             j += i;
21         } while ( j < N );
22     }
23     cnt[0] = prime[0];
24     for ( int i = 1; i < N; i++ )
25     {
26         cnt[i] = cnt[i - 1] + prime[i];        
27     }
28 }
29 
30 int main ()
31 {
32     get();
33     int a, b;
34     while ( cin >> a >> b )
35     {
36         int c = cnt[b] - cnt[a - 1];
37         cout << ( prime[c] ? "YES" : "NO" ) << endl;
38     }
39     return 0;
40 }

即在枚举i的倍数的时候是从:j = i * i 开始的,其实原理很简单。

需要注意的是:乘法在数据量较大的时候可能会有溢出,所以maybe需要转化为64位整数。

4090:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int N = 224738;
 6 const int M = 20000;
 7 bool isPrime[N];
 8 int prime[M];
 9 int cnt;
10 
11 void get()
12 {
13     memset( isPrime, true, sizeof(isPrime) );
14     isPrime[0] = isPrime[1] = false;
15     for ( int i = 2; ; i++ )
16     {
17         int j = i * i;
18         if ( j >= N ) break;
19         do
20         {
21             isPrime[j] = false;
22             j += i;
23         } while ( j < N );
24     }
25     cnt = 0;    
26     for ( int i = 0; i < N; i++ )
27     {
28         if ( isPrime[i] )
29         {
30             prime[cnt++] = i;
31         }
32     }    
33 }
34 
35 int main ()
36 {
37     get();
38     int n;    
39     while ( scanf("%d", &n) != EOF )
40     {
41         n = n * 2 - 1;
42         printf("%d%d\n", prime[n - 1], prime[n]);
43     }
44     return 0;
45 }

 

posted @ 2015-04-09 12:08  hxy_has_been_used  阅读(141)  评论(0编辑  收藏  举报