HDU 4548 美素数

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;
}

 

posted @ 2019-03-05 19:44  鹤花之歌  阅读(131)  评论(0编辑  收藏  举报