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 中存放了到数字 i 为止的所有美素数个数,结果直接用左右边界做减法即可
以上是关于HDU 4548——美素数的主要内容,如果未能解决你的问题,请参考以下文章