description:
s number is the number which the sum of every digit is a prime number,such as 98,29.output the number of S number in [l,r]
input
2
4 30
49 173
output
12
45
古人云:朝闻夕死,昨晚背gis代码的时候突然想到了卡了的水题正解
题意:求出给定区间的每个各个位上加和是质数的个数
dp[位数][各个位上的和]
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[20][200];
bool isprime[200];
void init()
{
memset(isprime,0,sizeof(isprime));
isprime[2]=isprime[3]=1;
for(int i=4;i<=190;i++)
{
bool flag=1;
for(int j=2;j<i&&flag;j++)
{
if(i%j==0)
{
flag=0;
// isprime[i]=0;
break;
}
}
if(flag) isprime[i]=1;
}
// for(int i=1;i<180;i++)if(isprime[i])printf("i=%d ",i);
}
int num[20],len;
void cal(int n)
{
len=0;
memset(num,0,sizeof(num));
memset(dp,-1,sizeof(dp));
while(n)
{
num[++len]=n%10;
n/=10;
}
num[len+1]=0;
}
int dfs(bool flag,int pos,int sum)
{
if(pos==0)return isprime[sum]==1;
if(!flag&&dp[pos][sum]!=-1)return dp[pos][sum];
int ans=0;
int maxn=flag?num[pos]:9;
for(int i=0;i<=maxn;i++)
{
ans+=dfs(i==maxn&&flag,pos-1,sum+i);
}
if(!flag)dp[pos][sum]=ans;
return ans;
}
int main()
{
init();
int t,l,r;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&l,&r);
cal(l-1);
int ansl=dfs(1,len,0);
cal(r);
int ansr=dfs(1,len,0);
printf("%d\n",ansr-ansl);
}
return 0;
}