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

HDU 4548——美素数

时间:2019-08-25 11:49:23      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:span   sizeof   链接   turn   using   特点   code   style   nbsp   

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4548

 

题解

#include<cstring>
#include<iostream>
using namespace std;

const int n=1000005;
int prime[1000005];
bool vis[1000005];
int cnt[1000005]; //记录到数字 j为止的美素数个数 
void oula(){ //通过欧拉筛打表 
    int cnt=0;
    memset(prime,0,sizeof(prime));
    memset(vis,false,sizeof(vis));
    for(int t=2;t<=n;t++) { //枚举 t
        if(!vis[t]) //找到没有被删除的数 
            prime[cnt++]=t; //加入素数表 
        for(int j=0;j<cnt && t*prime[j]<=n;j++){ //枚举素数表 
            vis[t*prime[j]]=true; //标记 t和素数表相乘的合数 
            if(t%prime[j]==0) //如果遇到枚举的素数是 t的约数,跳出循环 
                break;
        }
    }
}
void beautfulprime(){
    cnt[0]=0;
    cnt[1]=0;
    for(int j=2;j<1000005;j++){
        cnt[j]=cnt[j-1]; //继承到上一个数字的美素数的个数,再计算当前数字是否满足要求
         
        long long sum=0;
        int k=j;
        while(k){
            sum+=k%10;
            k/=10;
        }
        if(vis[j]==false && vis[sum]==false) //数字 j是素数,其各位数字之和也是素数 
            cnt[j]++;
    }
}

int main() {
    int m;
    scanf("%d",&m);
    oula();
    beautfulprime();
    int l,r;
    for(int t=0; t<m; t++) {
        scanf("%d%d",&l,&r);
        printf("Case #%d: %lld\n",t+1,cnt[r]-cnt[l-1]);
    }
    return 0;
}

 

由于数字很大,需要打表以免超时

通过欧拉筛进行第一次打表,找出到右边界的所有素数,然后针对美素数的特点在得到的表格中进行第二次打表

数组 cnt 中存放了到数字 为止的所有美素数个数,结果直接用左右边界做减法即可

HDU 4548——美素数

标签:span   sizeof   链接   turn   using   特点   code   style   nbsp   

原文地址:https://www.cnblogs.com/xxwang1018/p/11407234.html

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