HDU - 4722 Good Numbers 找规律 or 数位dp模板
Posted euzmin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.
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 20Sample Output
Case #1: 0 Case #2: 1Hint
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 }
以上是关于HDU - 4722 Good Numbers 找规律 or 数位dp模板的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1847 Good Luck in CET-4 Everybody!(博弈找规律)