zoukankan      html  css  js  c++  java
  • 51nod 1230:幸运数

    51nod 1230:幸运数

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1230

    题目大意:如果一个数各个数位上的数字之和是质数,并且各个数位上的数字的平方和也是质数,则称它为幸运数。例如:120是幸运数,因为120的数字之和为3,平方和为5,均为质数,所以120是一个幸运数字。给定x,y,求x,y之间( 包含x,y,即闭区间[x,y])有多少个幸运数。

    数位DP

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=22;
     6 int dig[maxn],prime[1459]={0},num_prime=0,T;
     7 ll f[maxn][163][1459],x,y;
     8 bool p[1459]={1,1};
     9 ll dfs(int pos,int sum,int sqrsum,int limit){
    10     if (pos<0) return (!p[sum])&&(!p[sqrsum]);
    11     if (!limit&&f[pos][sum][sqrsum]!=-1) return f[pos][sum][sqrsum];
    12     ll res=0;
    13     int last=limit?dig[pos]:9;
    14     for (int i=0;i<=last;i++){
    15         res+=dfs(pos-1,sum+i,sqrsum+i*i,limit&&(i==last));
    16     }
    17     if (!limit) f[pos][sum][sqrsum]=res;
    18     return res;
    19 }
    20 ll solve(ll n){
    21     int len=0;
    22     while (n){
    23         dig[len++]=n%10;
    24         n/=10;
    25     }
    26     return dfs(len-1,0,0,1);
    27 }
    28 void init(){
    29     memset(f,-1,sizeof(f));
    30     for(long i=2;i<1459;i++){
    31         if(!p[i])prime[num_prime++]=i;
    32         for(long j=0;j<num_prime&&i*prime[j]<1459;j++){
    33             p[i*prime[j]]=1;
    34             if(!(i%prime[j]))break;
    35         }
    36     }
    37 }
    38 int main(void){
    39     init();
    40     scanf("%d",&T);
    41     while(T--){
    42         scanf("%lld%lld",&x,&y);
    43         printf("%lld
    ",solve(y)-solve(x-1));
    44     }
    45 }
  • 相关阅读:
    测试开发面试集锦_数据库
    测试开发面试集锦_linux
    测试开发面试题集锦_java
    Java中equals 和==的区别
    定时清理文件shell脚本
    java文件上传,upload使用
    python 获取错误日志,并发送邮件
    c语言代码审计规范
    渗透测试之nmap
    渗透测试之GoogleHack
  • 原文地址:https://www.cnblogs.com/barrier/p/6725764.html
Copyright © 2011-2022 走看看