HDU 4548——美素数

Posted xxwang1018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4548——美素数相关的知识,希望对你有一定的参考价值。

链接: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——美素数的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4548——美素数

HDU 4548 美素数 素数题解

杭电(hdu)ACM 4548 美素数

HDU4548 美素数打表前缀和

HDOJ4548-美素数(前缀和,线性筛)

hdoj 4548 美素数 打表