标签:数字 研究 右值 cst 整数 进制 input 素数 clu
Problem Description
小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识。
问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“美素数”,如29,本身是素数,而且2+9 = 11也是素数,所以它是美素数。
给定一个区间,你能计算出这个区间内有多少个美素数吗?
Input
第一行输入一个正整数T,表示总共有T组数据(T <= 10000)。
接下来共T行,每行输入两个整数L,R(1<= L <= R <= 1000000),表示区间的左值和右值。
Output
对于每组数据,先输出Case数,然后输出区间内美素数的个数(包括端点值L,R)。
每组数据占一行,具体输出格式参见样例。
Sample Input
3 1 100 2 2 3 19
Sample Output
Case #1: 14 Case #2: 1 Case #3: 4
题解:emm如中文所示。这题难点并不在于实现,而是防止TLE。
所以不仅仅素数要打表,美素数自己也要打表。我还没做这道题的时候,我们ACM群就有人说了(?)所以一开始就是冲着打两个表的目标写的。。。
众所周知,第一个打素数表的代码是我直接复制的。。。//论为什么我现在自己都不会写冒泡排序,因为每次都是直接看模板没有自己写过orz,惭愧,该背了
总结一下:1.打美素数的表。
2.实现区间美素数个数的延续性,
比如15不是美素数,但是[2,14]与到[2,15]的美素数个数是一样的,
就不能简单地因为它自己不是美素数,就不存储之前的美素数个数。
3.注意如何收集一个数的各位数字。
#include <cstdio> #include <iostream> #include <cmath> #include <string> #include <map> #include <cstring> #include <algorithm> #include <math.h> #include <queue> using namespace std; const int maxn=1000007; //我们先打个1000000以内的表 int is_prime[maxn]; //这个表示i这个数是不是质数, 1表示是质数,0表示不是 int num[maxn]; //存下所有的素数,质数; int preprime[1000007]; void db(){ for(int i=2;i<=1000000;i++) is_prime[i]=1; for(int i=2;i<=1000000;i++){ if(is_prime[i]==1) { num[i]=i;//存入质数表 // printf("质数:%d\n",i); for(int j=i+i;j<=1000000;j+=i) is_prime[j]=0; // 从2*i开始,枚举这个素数的全部倍数,他的倍数肯定是合数,如果是合数,就置0; } } } void pretty() { memset(preprime,0,sizeof(preprime)); int counting=0; for(int i=1;i<=1000000;i++) { int summer=0,box; box=i; if(num[i]!=i) { preprime[i]=counting; continue; } while(box>0) { int x=box%10; summer+=x; box=box/10; } if(num[summer]==summer) { counting++; // printf("找到一个美素数\n");//测试用 // printf("i:%d,summer=%d,cnt=%d\n",i,summer,counting);//测试用 } preprime[i]=counting; } // for(int i=1;i<=100;i++) // { // printf("%d\n",preprime[i]); // } } int main() { int M=0,T,L,R; // scanf("%d",&M); // memset(num,0,sizeof(num)); db(); pretty(); while(scanf("%d",&T)!=EOF) { int cases[10007],casecnt=0,Tempbox; Tempbox=T; memset(cases,0,sizeof(cases)); while(T--) { scanf("%d%d",&L,&R); casecnt++; cases[casecnt]=preprime[R]-preprime[L-1]; /*if(L!=1) cases[casecnt]++;*/ } for(int i=1;i<=Tempbox;i++) { printf("Case #%d: %d\n",i,cases[i]); } } return 0; }
标签:数字 研究 右值 cst 整数 进制 input 素数 clu
原文地址:https://www.cnblogs.com/greenaway07/p/10479135.html