题意
求a~b内有多少个数满足本身是素数且各位相加后的结果也是素数
思路
1 不 是 素 数
因为这个debug了两个小时WA了四次也很可以
用普通素数筛就能做, 优化一下用Eratosthenes筛法也行
先说用普通素数筛:
只需要先筛选出1-54内的素数( 最大的各位相加是999999这个数 最大54 ) 然后对1~1000000所有数字求出各位相加的结果, 如果各位相加得到的是素数, 再判其本身是否是素数, 做前缀和就可以
用埃式筛法的话就直接判1~1000000内所有素数存一下, 做前缀和
AC代码
普通素数筛
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 1000000+5;
set<int> pr;
int pre[maxn];
void primer()
{
bool flag;
for( int i = 2; i < 60; i++ )
{
flag = 1;
for( int j = 2; j*j <= i; j++ )
{
if( i % j == 0 )
{
flag = 0;
break;
}
}
if(flag) pr.insert(i);
}
}
bool isprimer(int num)
{
if(num==1) return false;
for( int i = 2; i*i <= num; i++ )
{
if( num % i == 0 )
return false;
}
return true;
}
int main()
{
primer();
int dig, num;
pre[0] = 0;
for( int i = 1; i <= 1000000; i++ )
{
dig = i, num = 0;
while(dig)
{
num += dig % 10;
dig /= 10;
}
if( pr.count(num) )
{
if( isprimer(i) )
pre[i] = pre[i-1] + 1;
else
pre[i] = pre[i-1];
}
else pre[i] = pre[i-1];
}
int n, a, b;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&a,&b);
if( a > b ) swap(a, b);
printf("%d\n", pre[b]-pre[a-1]);
}
return 0;
}
埃式筛法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
const int maxn = 1000000+5;
bool ok[maxn];
int pre[maxn];
int main()
{
int dig, num;
ok[0] = 0, ok[1] = 1;
for( int i = 2; i <= 1000000; i++ )
{
if( !ok[i] )
{
dig = i, num = 0;
while(dig)
{
num += dig % 10;
dig /= 10;
}
if( !ok[num] )
{
pre[i] = 1;
}
for(int j = 2*i; j <= 1000000; j += i)
ok[j] = 1;
}
}
for(int i = 1; i <= 1000000; i++)
pre[i] += pre[i-1];
int n, a, b;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&a,&b);
if( a > b ) swap(a, b);
printf("%d\n", pre[b]-pre[a-1]);
}
return 0;
}