zoukankan      html  css  js  c++  java
  • HDU XXXX:求[L,R]的素数数量(数位DP)

    Problem G

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/131072K (Java/Other)
    Total Submission(s) : 62   Accepted Submission(s) : 28

    Font: Times New Roman | Verdana | Georgia

    Font Size:  

    Problem Description

    S number is the number which the sum of every digit is a prime number, such as number 98, 29. Output the number of S number in [L,R].

    Input

      First line contains T(T10) denoting the number of test cases.
      T cases follows For each cases: 
      There two numbers L,R.(0LR1016)

    Output

    For each case, output the number of S number.

    Sample Input

    2
    4 30
    49 173
    

    Sample Output

    12
    45

    题意:找出[L,R]里面素数的总和,即求出[0,R]-[0,L-1]就可以了。
    思路:因为数据范围在0~10^16那么大,所以不可以暴力了,考虑到每个位最多是9,那么最多15个9的话就是135个数那么多,因此我打了个判断135里面的数哪个是素数的表,然后就数位DP
     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 #define N 20
     6 int bit[N];
     7 long long dp[N][200][2];
     8 int prime[200];
     9 
    10 bool check(int x)
    11 {
    12     for(int i=2;i*i<=x;i++){
    13         if(x%i==0) return false;
    14     }
    15     return x!=1;
    16 }
    17 
    18 void P()
    19 {
    20     for(int i=2;i<=200;i++){
    21         if(check(i)){
    22              prime[i]=1;
    23         }
    24     }
    25 }
    26 //flag表示之前的数是否是上界的前缀(即后面的数能否任意填)。
    27 //flag为 1 表示之前的数不是前缀,可以任意填
    28 long long dfs(int pos,int st,int have,int flag)
    29 {
    30     if(!pos) return have;
    31     if(flag&&dp[pos][st][have]!=-1) return dp[pos][st][have];
    32     long long ans=0;
    33     int u=flag?9:bit[pos];
    34     for(int d=0;d<=u;d++){
    35         ans+=dfs(pos-1,st+d,prime[st+d],!flag&&d==u);
    36         //判断之前位置的和加上当前位置是否可以是一个素数
    37     }
    38     if(flag) dp[pos][st][have]=ans;
    39     return ans;
    40 }
    41 
    42 long long solve(long long s)
    43 {
    44     memset(bit,0,sizeof(bit));
    45     int l=0;
    46     while(s){
    47         bit[++l]=s%10;
    48         s/=10;
    49     }
    50     return dfs(l,0,0,0);
    51 }
    52 
    53 int main()
    54 {
    55     int t;
    56     cin>>t;
    57     memset(prime,0,sizeof(prime));
    58     P();
    59     while(t--){
    60         memset(dp,-1,sizeof(dp));
    61         long long s1,s2;
    62         cin>>s1>>s2;
    63 //        cout<<solve(s2)<<" "<<solve(s1-1)<<endl;
    64         cout<<solve(s2)-solve(s1-1)<<endl;
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    中文编码问题
    TCP网络参数优化
    I/O的整体介绍
    TCP/IP
    Java序列化技术
    WEB请求过程(http解析,浏览器缓存机制,域名解析,cdn分发)
    λ(lambda)表达式
    HeapByteBuffer和DirectByteBuffer以及回收DirectByteBuffer
    锁的优化和注意事项
    java的NIO和AIO
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5671656.html
Copyright © 2011-2022 走看看