码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-02-23 22:28:12      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

题意:

你现在来到了一个所有的数都模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 }
代码君

 

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

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4298333.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!