首页 > 代码库 > 周一s:E - 美素数

周一s:E - 美素数

题目:
    小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识。 
  问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“美素数”,如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

最开始直接for,然后超时了。
然后for到sqrt(n)--n的平方。还是超时。

为了比较程序修改后运行时间的快慢
首先,我们来认识一下#include<math.h>
讲道理我是没怎么去理解,反正这么用就对了。T_T
...表示省略
 1 #include <time.h>//测运行时间 
...
2 int main() 3 { 4 ... 5 clock_t start,end;//初始化 放哪都行(开始前面任意位置) 6 ... 7 start = clock();//开始计时时间 8 ... 9 end=clock();/计时结束时间 10 printf("消耗: %d毫秒\n",end-start);//输出测运行时间 11 .... 12 return 0; 13 }

  最后选择了所谓的打表,╮(╯▽╰)╭好吧,我也不是很明白那些概念。

  简单来说就是——用空间换时间。好吧,这也是临时学会的名词≥▽≤

    预先把素数的表列出来存好,用时直接取。

  第一步

    给定1000000+1(直接从1开始,0开始怕搞混)的数组。PS:直接在mian里定义程序运行会崩°(°ˊДˋ°) °求大神解释。

    然后放在外面全局定义就没事。

  第二步

    数组下标1为0,2为1,其余开始奇数为1,偶数为0。

  第三步

    筛选不是素数的数给0,叫什么筛选法来着。。。不擅长记忆概念东西。。。ヽ(ˋДˊ)ノ

    for(i=3;i<=m;i++)
        if(d[i])
            for(j=i+i;j<=m;j+=i)
            {
                d[j]=0;
            }

    意思就是从3开始,依次把3、5、7... ...的倍数全部置0。(不是素数嘛)

  第四步

    把美素数求出来,求和再判断素数省略了。。。

  。。。关键的就那些了,就省略吧。

代码如下:

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include <time.h>//测运行时间 
 4 #define m 1000000
 5 int d[m+1]={0,0,1};
 6 int jia(int n)
 7 {
 8     int sum=0;
 9     if(n<10)
10     {
11         sum=n;
12     }
13     else
14         while(n)
15         {
16             sum+=n%10;
17             n/=10;
18         }
19     return sum;
20 }
21 int pan(int n)
22 {
23     int i,num=1,flag=0;
24     if(n%2==0||n%3==0||n%5==0||n%7==0)//没 n==1 判断   相加为1的肯定为偶数 
25     {
26         num=0;
27     }
28     if(n==2||n==3||n==5||n==7)//最大999999相加为54  54内就 2 3 5 7倍数
29         num=1;
30     return num;
31 }
32 int main()
33 {
34     int a1,a2,a3=1,b,c,sum,e;
35     int d1[10000],i,j,k,l;
36     clock_t start,end;//测运行时间
37     for(i=3;i<=m;i++)
38     {
39         if(i%2==0)
40             d[i]=0;
41         else 
42         {
43             d[i]=1;
44         }
45     }
46     for(i=3;i<=m;i++)
47         if(d[i])
48             for(j=i+i;j<=m;j+=i)
49             {
50                 d[j]=0;
51             }
52     for(k=3;k<=m;k++)
53     {
54         if(d[k])
55             {        
56                 if(!pan(jia(k)))
57                 {
58                     d[k]=0;
59                 }    
60             }
61     }
62     for(k=3;k<=m;k++)
63     {
64         d[k]+=d[k-1]; //这个也是个关键,一开始写在scanf后判断b到c有多少相加,又超时了。T_T。所以就先把其加好,反正不是素数为零,最后相减计算快
65     }
66             
67     scanf("%d",&a1);a2=a1; 
68     while(a1--)
69     {
70         sum=0;
71         scanf("%d%d",&b,&c);
72         start = clock();//测运行时间 
73         d1[a1]=d[c]-d[b-1];
74     }
75     while(a2--)
76     {
77         printf("Case #%d: %d\n",a3,d1[a2]);//end-start测运行时间 
78         a3++;
79     }
80     end=clock();//测运行时间 
81 //    printf("消耗: %d毫秒\n",end-start);//测运行时间 
82     return 0;
83 } 

 

周一s:E - 美素数