• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 博客园
  • 联系
  • 订阅
  • 管理

View Post

HDU 4548

题意:

  给你一个区间,问你这个区间中的数既是素数又是美素数的数有多少个?美素数:首先这个数本身必须是素数并且它的各位数字的和也是素数; 如29,本身是素数, 而且2+9 = 11也是素数, 所以它是美素数.

 
分析:
  要筛选素数直接用埃拉托塞尼筛素数法, 然后枚举从n~m(n为1时从2开始)中的美素数, 是不是特简单觉得肯定能AC; 不过提交显示TLE, 为什么呢?因Tmax =1000, mmax = 1000000, 这样筛一下就已经超时了, 更不说再去枚举了; 那可以这样在输入数据之前就将1e6之内的素数筛出来, 再枚举n~m,然而还是不行,1e6有将80000个素数照样TLE;对于输入数据量比较大而结果很小时, 可以采用计数排序.
 
 
 
 
代码如下:
 
 
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <fstream>
 5 #include <ctime>
 6 #include <cmath>
 7 #include <cstdlib>
 8 #include <algorithm>
 9 #include <set>
10 #include <map>
11 #include <list>
12 #include <stack>
13 #include <queue>
14 #include <iterator>
15 #include <vector>
16 
17 using namespace std;
18 
19 #define LL long long
20 #define INF 0x3f3f3f3f
21 #define MOD 1000000007
22 #define MAXN 10000010
23 #define MAXM 1000010
24 
25 const int maxn = 1000005;
26 int vis[maxn], prime[maxn];
27 
28 void sieve(int n)
29 {
30     int m = sqrt(n+0.5);
31     memset(vis, 0, sizeof(vis));
32     memset(prime, 0, sizeof(prime));
33     for(int i = 2; i <= m; i++ )
34         if(!vis[i])
35             for(int j = i*i; j <= n; j += i )   //每次增加i
36                 vis[j] = 1;
37 }
38 
39 int count_sum(int n)
40 {
41     int sum = 0;
42     while(n > 0)
43     {
44         sum += n%10;
45         n /= 10;
46     }
47     return sum;
48 }
49 
50 void gen_prime(int n)
51 {
52     sieve(n);
53     for(int i = 2; i <= n; i++ )
54     {
55         if(!vis[i]&&!vis[count_sum(i)])
56             prime[i] = prime[i-1] + 1;
57         else
58             prime[i] = prime[i-1];
59     }
60 }
61 
62 int main()
63 {
64     gen_prime(maxn);
65     int t;
66     int kase = 0;
67     scanf("%d", &t);
68     while(t--)
69     {
70         int n, m;
71         scanf("%d%d", &n, &m);
72         printf("Case #%d: %d\n", ++kase, prime[m]-prime[n-1]);    //表示区间[n,m]的美素数个数,区间的长度为m-(n-1).
73     }
74 
75     return 0;
76 }

 

 
 
  
 
 
 
 
 

posted on 2015-08-21 18:32  tony-cao  阅读(244)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3