Description
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.
Input
The 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).
Output
For test case X, output "Case #X: " first, then output the number of good numbers in a single line.
题目大意:求a~b中,位上所有数字加起来能整除10的数有多少个。
思路:位数DP。dp[i][j][k]表示第i位小于j,除以10余k的数的个数,j=10只是为了i+1的j=1准备的……第一次写这个写得有点挫啊……
PS:有数学方法但是我不会,我只知道接近于对于0~n接近于n/10……
代码(109MS):
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXN = 22; 9 10 LL dp[MAXN][MAXN][MAXN]; 11 //i位,字头小于j,和为k的数一共有多少个 12 LL a, b; 13 int T; 14 15 void init() { 16 dp[0][10][0] = 1; 17 for(int i = 1; i <= 19; ++i) { 18 for(int k = 0; k <= 9; ++k) dp[i][1][k] = dp[i - 1][10][k]; 19 for(int j = 2; j <= 10; ++j) { 20 for(int k = 0; k <= 9; ++k) 21 dp[i][j][k] = dp[i][1][(k + 10 - (j - 1)) % 10] + dp[i][j - 1][k]; 22 } 23 } 24 } 25 26 int t[MAXN]; 27 28 LL calculate(LL n) { 29 int cnt = 0; 30 while(n) t[++cnt] = n % 10, n /= 10; 31 int sum = 0; 32 LL ret = 0; 33 for(int i = cnt; i > 0; --i) { 34 ret += dp[i][t[i]][(10 - sum) % 10]; 35 sum = (sum + t[i]) % 10; 36 } 37 return ret; 38 } 39 40 int main() { 41 ios::sync_with_stdio(false); 42 cin>>T; 43 init(); 44 for(int t = 1; t <= T; ++t) { 45 cin>>a>>b; 46 cout<<"Case #"<<t<<": "<<calculate(b + 1) - calculate(a)<<endl; 47 } 48 }