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 <= 10000) , indicating the number of test cases.

Each test case comes with a single line with two numbers A and B (0 <= A <= B <= 10
18).OutputFor test case X, output "Case #X: " first, then output the number of good numbers in a single line.Sample Input

2
1 10
1 20

Sample Output

Case #1: 0
Case #2: 1

Hint

The answer maybe very large, we recommend you to use long long instead of int.

 这题有两种做法,找规律或者数位dp法一找规律:从0开始打表会发现每10个数都有一个good number 0 - 9, 10- 19 …… 这样假如要求0 到123,只需要求 0 - 119的 有12个good numbers,再暴力求120 - 123的即可。法二数位dp:这道题在数位dp中算是模板入门了吧。

法一代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <set>
10 #include <cstring>
11 using namespace std;
12 typedef long long ll;
13 #define inf 0x3f3f3f3f
14 char st[12];
15 ll x;
16 int main()
17 {
18     int t;
19     ll a, b;
20     scanf("%d", &t);
21     ll cnta = 0, cntb = 0;
22     for(int cas = 1; cas <= t; ++cas) {
23         cnta = 0;
24         cntb = 0;
25         scanf("%lld %lld", &a, &b);
26         a--;
27         if(a < 0) cnta--;
28         a = max(a, ll(0));
29         ll ma = a % 10;
30         cnta += a / 10;
31         for(ll i = 0; i <= ma; ++i) {
32             ll sum = 0;
33             ll v = a / 10 * 10+ i;
34             while(v) {
35                 sum += v % 10;
36                 v /= 10;
37             }
38             if(sum % 10 == 0) cnta++;
39         }
40         ll mb = b % 10;
41         cntb += b / 10;
42         for(ll i = 0; i <= mb; ++i) {
43             ll sum = 0;
44             ll v = b / 10 * 10+ i;
45             while(v) {
46                 sum += v % 10;
47                 v /= 10;
48             }
49             if(sum % 10 == 0) cntb++;
50         }
51
52         printf("Case #%d: %lld\n", cas, cntb - cnta);
53     }
54     return 0;
55 }

法二代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <set>
10 #include <cstring>
11 using namespace std;
12 typedef long long ll;
13 #define inf 0x3f3f3f3f
14 ll dp[22][188];
15 ll ed[22];
16 ll dfs(int pos, ll sum, bool lmt) {
17     if(pos == 0) {
18         if(sum % 10 == 0) return 1;
19         return 0;
20     }
21
22     if(!lmt && dp[pos][sum] != -1) return dp[pos][sum];
23     ll ans = 0;
24     ll up =  lmt? ed[pos] : 9;
25     for(ll i = 0; i <= up; ++i) {
26         ans += dfs(pos - 1, sum + i, lmt && i == ed[pos]);
27     }
28     if(!lmt) dp[pos][sum] = ans;//统计状态
29     return ans;
30 }
31 ll solv(ll x) {
32     if(x < 0) return 0;
33     int len = 0;
34     while(x) {
35         ed[++len] = x % 10;
36         x /= 10;
37     }
38
39     return dfs(len, 0, 1);
40 }
41
42 int main()
43 {
44     int t;
45     ll a, b;
46     scanf("%d", &t);
47     memset(dp,-1,sizeof(dp));
48     for(int cas = 1; cas <= t; ++cas) {
49
50         scanf("%lld %lld", &a, &b);
51         printf("Case #%d: %lld\n", cas, solv(b) - solv(a - 1));
52     }
53     return 0;
54 }



原文地址:https://www.cnblogs.com/zmin/p/8809020.html

时间: 2024-10-19 08:18:41

HDU - 4722 Good Numbers 【找规律 or 数位dp模板】的相关文章

hdu 4722 Good Numbers(初涉数位dp)

http://acm.hdu.edu.cn/showproblem.php?pid=4722 大致题意:若一个整数的各位数字之和是10的倍数,称这个数为"good number".给出区间[A,B],求出该区间内"good number"的数的个数. 第一道数位dp,折腾了半天才明白怎么回事. 设dp[site][mod]表示到第site位(由高位向低位)前面各位数字之和对10取余为mod的数的个数,进行记忆化搜索.有两个很重要的点,首先是变量up,表示是否到达边界

HDU 4722 Good Numbers (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:数位dp,dp[i][j]表示到第i位,数字和%10为j,然后进行dp,注意完全匹配的情况是要+1,而其他情况是从0 到 9 都要考虑 代码: #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; int

hdu 4952 Number Transformation (找规律)

题目链接 题意:给你个x,k次操作,对于第i次操作是:要找个nx,使得nx是>=x的最小值,且能整除i,求k次操作后的数 分析: 经过打表找规律,会发现最后的x/i,这个倍数会趋于一个固定的值,求出这个固定的值和K相乘就可以了, 为什么会趋于固定的值呢,因为最后虽然i在不断增长,但是x也是在增长的,每次的倍数会回退一个发现 有余数,然后再加上一个,所以趋于稳定. 官方题解: 1 #include <iostream> 2 #include <cstdio> 3 #includ

hdu 4861 Couple doubi (找规律 )

题目链接 可以瞎搞一下,找找规律 题意:两个人进行游戏,桌上有k个球,第i个球的值为1i+2i+?+(p−1)i%p,两个人轮流取,如果DouBiNan的值大的话就输出YES,否则输出NO. 分析:解题报告 1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 int main() 6 { 7 int k, p; 8 while(cin>>k>>p) 9 { 10 if(k/

hdu 4722 Good Numbers(dp)

public static void main(String[] args) { String a=null; if("aa".equals(a))//这种情形,不出现空指针异常 //if(a.equals("aa"))//出现空指针异常 { System.out.println(true); } else { System.out.println(false); } } 上面的两句不同的比较语句测试,第一句不出现空指针异常,第二句出现. 所以在变量和常量比较的时候

HDU 4927 Series (找规律+JAVA)

题目链接:HDU 4927 Series 题意:给出一串N个元素的序列,作为第一串序列,第二串序列是第二串序列相邻元素的查值(即Bi=Ai+1-Ai)...第三串....一直到第N-1串是序列中只有一个数. 刚开始想到模拟一发,WA了一把,推出公式,发现是二项展开的系数(正负交替).组合数,果断要大数,苦逼JAVA不会.和一起队友摸索着,又T了一发,再想到组合数的递推.终于A了 C(a-1,b)=C(a,b)*a/(b-a+1) AC代码: import java.math.BigInteger

HDU 4919 打表找规律 java大数 map 递归

== oeis: 点击打开链接 瞎了,x.mod(BigInteger.ValueOf(2)).equal( BigInteger.ValueOf(1)) 写成了 x.mod(BigInteger.ValueOf(2)).equal( 1 ) T^T100块没了... import java.math.*; import java.util.*; import static java.lang.System.out; import java.io.*; public class Main { s

HDU 4861 Couple doubi(找规律|费马定理)

Couple doubi Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4861 Description DouBiXp has a girlfriend named DouBiNan.One day they felt very boring and decided to play some games. The rule of th

【HDU 4352】 XHXJ&#39;s LIS (数位DP+状态压缩+LIS)

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2422    Accepted Submission(s): 990 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful