• 51Nod1230 幸运数


    1230 幸运数 

    题目来源: HackerRank

    基准时间限制:1 秒

    空间限制:131072 KB

    分值: 320 

    难度:7级算法题

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

    Input

    第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
    第2 - T + 1行:每行2个数,X, Y中间用空格分割。(1 <= X <= Y <= 10^18)

    Output

    输出共T行,对应区间中幸运数的数量。

    Input示例

    2
    1 20
    120 130

    Output示例

    4
    1

    解析:

    一看就是打表数位dp啊。。。

    考虑到各个位上数字之和及数字的平方和不大,就先把范围内所有质数筛出来。

    然后就是数位dp的套路了。

    详见代码。

    我还是太弱了不知道说啥。。。

     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long
     8 int t;
     9 ll x,y;
    10 ll f[20][200][1500];
    11 int prime[1500],tot;
    12 bool notprime[1500];
    13 int a[20];
    14 void get_prime(){
    15     notprime[0]=true;
    16     notprime[1]=true;
    17     for (int i=2;i<=1499;++i){
    18         if (!notprime[i]) prime[++tot]=i;
    19         for (int j=1;j<=tot&&i*prime[j]<=1499;++j){
    20             notprime[i*prime[j]]=true;
    21             if (i%prime[j]==0) break;
    22         } 
    23     }
    24 }
    25 ll dfs(int pos,int limit,int sum,int squ){
    26     if (pos<=0) return ((!notprime[sum])&&(!notprime[squ]));
    27     if (!limit&&f[pos][sum][squ]!=-1) return f[pos][sum][squ];
    28     int lim=limit?a[pos]:9;
    29     ll res=0;
    30     for (int i=0;i<=lim;++i){
    31         res+=dfs(pos-1,limit&&(i==lim),sum+i,squ+i*i);
    32     }
    33     if (!limit) f[pos][sum][squ]=res;
    34     return res;
    35 }
    36 ll solve(ll xx){
    37     int len=0;
    38     while (xx){
    39         a[++len]=xx%10;
    40         xx/=10;
    41     }
    42     return dfs(len,1,0,0);
    43 }
    44 int main(){
    45     memset(f,-1,sizeof(f));
    46     get_prime();
    47     scanf("%d",&t);
    48     while (t--){
    49         scanf("%lld%lld",&x,&y);
    50         printf("%lld
    ",solve(y)-solve(x-1));
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    第一本书 第七章(课后题)
    java基础小测试
    随笔1
    随笔
    日记 晴 2017.7.30
    自我介绍
    与或非逻辑运算符 与或非位运算符
    日记1 天气阴 阵雨
    归并排序的两个版本实现代码
    Winedt打开tex文件报错error reading的解决方案
  • 原文地址:https://www.cnblogs.com/gjc1124646822/p/8278404.html
Copyright © 2020-2023  润新知