我今天已经水了好多题了
请不要再催更了(QwQ)
解析:
一看就是打表数位dp啊。。。
考虑到各个位上数字之和及数字的平方和不大,就先把范围内所有质数筛出来。
然后就是数位dp的套路了。
详见代码。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; #define ll long long int t; ll x,y; ll f[20][200][1500]; int prime[1500],tot; bool notprime[1500]; int a[20]; void get_prime(){ notprime[0]=true; notprime[1]=true; for (int i=2;i<=1499;++i){ if (!notprime[i]) prime[++tot]=i; for (int j=1;j<=tot&&i*prime[j]<=1499;++j){ notprime[i*prime[j]]=true; if (i%prime[j]==0) break; } } } ll dfs(int pos,int limit,int sum,int squ){ if (pos<=0) return ((!notprime[sum])&&(!notprime[squ])); if (!limit&&f[pos][sum][squ]!=-1) return f[pos][sum][squ]; int lim=limit?a[pos]:9; ll res=0; for (int i=0;i<=lim;++i){ res+=dfs(pos-1,limit&&(i==lim),sum+i,squ+i*i); } if (!limit) f[pos][sum][squ]=res; return res; } ll solve(ll xx){ int len=0; while (xx){ a[++len]=xx%10; xx/=10; } return dfs(len,1,0,0); } int main(){ memset(f,-1,sizeof(f)); get_prime(); scanf("%d",&t); while (t--){ scanf("%lld%lld",&x,&y); printf("%lld ",solve(y)-solve(x-1)); } return 0; }
学废了扣1.没学废扣眼珠子
请大家