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
思路:
打表。质数的倍数一定是合数,利用这点我们就可以把合数都标记出来
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int M = 1000010; 5 int isprime[M]; 6 int isbuprime_sum[M]; 7 void prime() 8 { 9 memset(isprime, 0, sizeof(isprime)); 10 memset(isbuprime_sum, 0, sizeof(isbuprime_sum)); 11 isprime[0] = 1; 12 isprime[1] = 1; //初始化 13 for (int i = 2; i < M; i++) 14 { 15 if (isprime[i]) //判断,是合数就直接跳过 16 continue; 17 for (int j = i+i; j < M; j += i) //先把素数的倍数(就是合数)都标记好 18 { 19 isprime[j] = 1; 20 } 21 } 22 } 23 24 int sumsum(int k) 25 { 26 int sum = 0; 27 while (k) 28 { 29 sum += k % 10; //各个位数的和,以便后面判断 30 k /= 10; 31 } 32 return sum; 33 } 34 35 int main() 36 { 37 prime(); 38 isbuprime_sum[0] = isbuprime_sum[1] = 0; 39 for (int i = 2; i < M; i++) 40 { 41 if (!isprime[i] && !isprime[sumsum(i)]) //之前素数被标记为0了 42 isbuprime_sum[i] = isbuprime_sum[i - 1] + 1; //是美素数就计一次数 43 else 44 isbuprime_sum[i] = isbuprime_sum[i - 1]; //不是美素数,当前计数不变 45 } 46 int T,ans=1; 47 cin >> T; 48 while (T--) 49 { 50 int R, L; 51 cin >> L >> R; 52 cout << "Case #" << ans++ << ": " << isbuprime_sum[R] - isbuprime_sum[L - 1] << endl; //输出L-1因为包括左右端点 53 54 } 55 56 return 0; 57 }
心得:
再get一招,可以这样找素数,简直棒棒的,哈哈,集训太快了,转眼就快结束了。还真有点舍不得就回家了呢,说多了,学到知识更重要,加油加油啦~~~~~~~?(^∇^*)
时间: 2024-11-17 06:52:52