码迷,mamicode.com
首页 > 其他好文 > 详细

HDU XXXX:求[L,R]的素数数量(数位DP)

时间:2016-07-14 21:24:02      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

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 long long dfs(int pos,int st,int have,int flag)
28 {
29     if(!pos) return have;
30     if(flag&&dp[pos][st][have]!=-1) return dp[pos][st][have];
31     long long ans=0;
32     int u=flag?9:bit[pos];
33     for(int d=0;d<=u;d++){
34         ans+=dfs(pos-1,st+d,prime[st+d],flag||d<u);
35         //判断之前位置的和加上当前位置是否可以是一个素数
36     }
37     if(flag) dp[pos][st][have]=ans;
38     return ans;
39 }
40 
41 long long solve(long long s)
42 {
43     memset(bit,0,sizeof(bit));
44     int l=0;
45     while(s){
46         bit[++l]=s%10;
47         s/=10;
48     }
49     return dfs(l,0,0,0);
50 }
51 
52 int main()
53 {
54     int t;
55     cin>>t;
56     memset(prime,0,sizeof(prime));
57     P();
58     while(t--){
59         memset(dp,-1,sizeof(dp));
60         long long s1,s2;
61         cin>>s1>>s2;
62 //        cout<<solve(s2)<<" "<<solve(s1-1)<<endl;
63         cout<<solve(s2)-solve(s1-1)<<endl;
64     }
65     return 0;
66 }

 

 

HDU XXXX:求[L,R]的素数数量(数位DP)

标签:

原文地址:http://www.cnblogs.com/fightfordream/p/5671656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!