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

    题目大意

    如果一个数各个数位上的数字之和是质数,并且各个数位上的数字的平方和也是质数,则称它为幸运数。
    例如: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|

    Solution

    这一题显然可以这状态为dp[pos][sum][sum1][0/1]经典的数位dp,pos到第pos位

    sum数位和maxsum=9*18,sum1平方和maxsum1=9*9*18,状态很少,但0/1不能

    传递,所以每次只用重新算压在lim上的数的方案数就行了。记忆化搜索即可。

    Code

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define fo(i,a,b) for(int i=a;i<=b;i++)
     6 #define fd(i,a,b) for(int i=a;i>=b;i--)
     7 #define fh(i,x) for(int i=head[x];i;i=next[i])
     8 typedef long long LL;
     9 inline int max(int x,int y) {return (x<y)?y:x;}
    10 inline int min(int x,int y) {return (x<y)?x:y;}
    11 inline LL read() {
    12     LL x=0,f=1;char ch=getchar();
    13     while(ch<'0'||ch>'9') f=(ch=='-')?-1:f,ch=getchar();
    14     while(ch>='0'&&ch<='9') x=x*10+(ch-'0'),ch=getchar();return f*x;
    15 }
    16 const int N=2e3+50,MAXN=2e3;
    17 int prime[N],tot;
    18 LL dp[20][200][N],dig[20];
    19 bool isprime[N];
    20 void init() {
    21     memset(dp,-1,sizeof(dp));
    22     memset(isprime,1,sizeof(isprime));
    23     isprime[1]=false;
    24     for(int i=2;i<=MAXN;i++) {
    25         if(isprime[i])prime[++tot]=i;
    26         for(int j=1;j<=tot&&i*prime[j]<=MAXN;j++) {
    27             isprime[i*prime[j]]=false;
    28             if(i%prime[j]==0)break;
    29         }
    30     }
    31 }
    32 LL dfs(int pos,int sum,int sum1,bool flag) {
    33     if(pos<1) return (isprime[sum]&&isprime[sum1]);
    34     if(!flag&&dp[pos][sum][sum1]!=-1) return dp[pos][sum][sum1];
    35     int lim=(flag)?dig[pos]:9;
    36     LL res=0;
    37     fo(i,0,lim) res+=dfs(pos-1,sum+i,sum1+i*i,flag&&(i==lim));
    38     if(!flag) dp[pos][sum][sum1]=res;
    39     return res;
    40 }
    41 LL solve(LL x) {
    42     int len=0;
    43     while(x) dig[++len]=x%10,x=x/10;
    44     return dfs(len,0,0,1);
    45 }
    46 int main() {
    48     init();
    49     int T=read();
    50     while(T--) {
    51         LL x=read(),y=read();
    52         printf("%lld
    ",solve(y)-solve(x-1));
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    Overloaded的方法是否可以改变返回值的类型
    parseXXX的用法
    java的类型转换问题。int a = 123456;short b = (short)a;System.out.println(b);为什么结果是-7616?
    UVA 10405 Longest Common Subsequence(简单DP)
    POJ 1001 Exponentiation(大数处理)
    POJ 2318 TOYS(计算几何)(二分)
    POJ 1265 Area (计算几何)(Pick定理)
    POJ 3371 Flesch Reading Ease (模拟题)
    POJ 3687 Labeling Balls(拓扑序列)
    POJ 1094 Sorting It All Out(拓扑序列)
  • 原文地址:https://www.cnblogs.com/patricksu/p/7868609.html
Copyright © 2011-2022 走看看