UVa 11105 (筛法) Semi-prime H-numbers

题意:

你现在来到了一个所有的数都模4余1的世界,也就是除了这种数没有其他的数了。

然而素数的定义依然没变,如果一个数不能写成两个非1数字的乘积,则它是素数。

比如,在这里5就变成了最小的素数。

两个素数相乘得到一个半素数,比如5×5 = 25就是最小的半素数。

求1~h之间有多少个半素数。

分析:

虽然是要求[1, h]之间半素数的个数,但向往常筛普通素数一样先把所有的4k+1的素数筛出来。

然后二重循环枚举半素数,最后统计区间内[1, h]的半素数个数SUMh

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <cmath>

 4 using namespace std;

 5 

 6 const int maxn = 1000000 + 1;

 7 bool vis[maxn + 10];

 8 int prime[100000], cnt, sum[maxn + 10];

 9 

10 void Init()

11 {

12     int m = sqrt(maxn + 0.5);

13     for(int i = 5; i <= m; i += 4) if(!vis[i])

14         for(int j = i * i; j <= maxn; j += i)

15             vis[j] = true;//H-素数筛选

16 

17     for(int i = 5; i <= maxn; i += 4) if(!vis[i]) prime[cnt++] = i;

18 

19     memset(vis, false, sizeof(vis));

20     for(int i = 0; i < cnt; i++)

21     {//筛选H-半素数

22         for(int j = i; j < cnt; j++)

23         {

24             long long k = (long long)prime[i] * (long long) prime[j];

25             if(k > (long long)maxn) break;

26             vis[k] = true;

27         }

28     }

29 

30     for(int i = 25; i <= maxn; i++) sum[i] = sum[i-1] + vis[i];

31 }

32 

33 int main()

34 {

35     freopen("in.txt", "r", stdin);

36     Init();

37     int n;

38     while(scanf("%d", &n) == 1 && n) printf("%d %d\n", n, sum[n]);

39 

40     return 0;

41 }
代码君

 

你可能感兴趣的:(number)