http://acm.hdu.edu.cn/showproblem.php?pid=4548
注意:
这道题使用打表即可。
但需要注意打表的方式。
AC代码1(这个代码有不好的地方)
不好的地方在于打表的方法是对每一个点进行判断是否是素数。推荐使用第二个方式打表,直接对素数进行标记的方式,两种方式一般会相差一个数量级。
#include<iostream>
#include<cmath>
using namespace std;
int a[1000002];
bool ifb2(int x){
if(x<=1)return false;
if(x==2)return true;
for(int i=2;i*i<=x;i++){
if(x%i==0)return false;
}
return true;
}
bool ifb1(int x)//第一个判断
{
int num=0;
while(x){
num+=x%10;
x/=10;
}
return ifb2(num);
}
int main(){
a[0]=a[1]=0;
a[2]=1;
for(int i=3;i<=1000002;i++){
if(ifb1(i)&&ifb2(i)){
a[i]=a[i-1]+1;
// cout<<i<<endl;
}else {
a[i]=a[i-1];
}
// if(a[i]==false){
// for(int j=2*i;j<=1000002;j+=i){
// a[j]=true;
// }
// }
}
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;cin>>T;
int index=1;
while(T--){
int l,r;cin>>l>>r;
int num=a[r]-a[l-1];
cout<<"Case #"<<index<<":"<<" ";
cout<<num<<endl;
index++;
}
return 0;
}
AC代码2(推荐)
#include<iostream>
#include<cmath>
using namespace std;
bool a[1000002];
int b[1000002];
long long unsigned z=0;
bool ifb2(int x){
if(x==1||x==0)return false;
if(x==2)return true;
for(int i=2;i*i<=x;i++){
if(x%i==0)return false;
}
return true;
}
bool ifb1(int x)//第一个判断
{
int num=0;
while(x){
num+=x%10;
x/=10;
}
return ifb2(num);
}
int main(){
a[0]=a[1]=true;
for(int i=2;i<=1000002;i++){
b[i]=b[i-1];
if(a[i]==false){
if(ifb1(i)){
b[i]++;
for(int j=2*i;j<=1000002;j+=i){
a[j]=true;
}
}else{
for(int j=2*i;j<=1000002;j+=i){
a[j]=true;
}
}
}
}
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;cin>>T;
int index=1;
while(T--){
int l,r;cin>>l>>r;
int num=b[r]-b[l-1];
cout<<"Case #"<<index<<":"<<" ";
cout<<num<<endl;
index++;
}
return 0;
}
两次提交。第一次提交的是代码1。可见相差还是蛮大的。