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(T≤10) denoting the number of test cases.
  T cases follows For each cases: 
  There two numbers L,R.(0≤L≤R≤1016)

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 }
时间: 2024-08-07 12:38:47

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

51Nod 1042 数字0-9的数量(数位DP)

题意: 求[l,r]中数字0-9分别出现的次数,11算两次1 思路: 数位dp题解好难写,直接贴代码吧 dp[i]表示[0, 10^i-1]中出现j的次数(按i位补全前导0,显然0-9出现的次数是相同的) 最后再减去每一位出现的前导零即可 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<

HDU 1058 Humble Numbers &amp;&amp; NOJ 1420 丑数 (数位dp)

Humble Numbers                          Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)                                          Total Submission(s): 18555    Accepted Submission(s): 8080 Problem Description A numb

51nod 1009 数字1的数量 数位dp

1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input 输入N(1 <= N <= 10^9) Output 输出包含1的个数 Input示例 12 Output示例 5 #include<bits/stdc++.h> using namespace std; #define

51nod 1042 数字0-9的数量 (数位dp、dfs、前导0)

1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 取消关注 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. Input 两个数a,b(1 <= a <= b <= 10^18) Output 输出共10行,分别是0-9出现的次数 Input示例 10 19 Output示例

51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input 输入N(1 <= N <= 10^9) Output 输出包含1的个数 Input示例 12 Output示例

HDU - 4722 Good Numbers 【找规律 or 数位dp模板】

If we sum up every digit of a number and the result can be exactly divided by 10, we say this number is a good number. You are required to count the number of good numbers in the range from A to B, inclusive. InputThe first line has a number T (T <=

HDU 4389 X mod f(x) (数位DP)

题目链接  HDU4389 题意  给出T个区间[L, R],统计L到R中有多少个满足条件的数. 限制条件为该数能被这个数的各位数字之和整除. 数据范围$1 <= L <= R <= 10^{9}$ 考虑数位DP 注意到f(x)最大为81,所以对1-81每一个和做一遍数位DP即可. f[pos][mod][sum][x] 表示当前处理到第pos位,当前的数位和对x取模的结果,当前的数位和,以及当前正在求的x = f(x) #include <bits/stdc++.h> us

HDU 6156 Palindrome Function 数位DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6156 题目描述: 求L~R所有的数的l~r进制的f(x), f(x) = 当前进制 如果回文串, f(x) = 1 其他情况 解题思路: 数位DP, 统计个数 , 需要作出改变的就是进制和回文 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #inclu

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6156 数位DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:如题. 解法:数位DP,暴力枚举进制之后,就转化成了求L,R区间的回文数的个数,这个直接做一个数位DP就好了.dp[jz][start][cur][state]表示jz进制下以start位起始到cur位状态为state(1表示已经回文,0表示没有回文)时回文数的个数. #include <bits/stdc++.h> using namespace std; typedef long