toj 4088 and 4090 筛素数之hxy优化算法

4088:

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

思路:筛呀筛,不过这里hxy加了一个优化。

 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需要转化为int64。

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 }

 

你可能感兴趣的:(算法)