Good Numbers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3360 Accepted Submission(s): 1064
Problem 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 <= 1018).
Output
For 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.Source
Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you: 5235 5234 5233 5232 5231
题目描述:假设一个数每位数上之和能被10整除,称这个数为好数,给定两个数,求在这个范围内的好数.
可以找规律,也可以采用递推。
设d[i][j]表示以i长度的对10取余为j的数的数量。
d[i+1][(j+k)%10]+=d[i][j];
通过d[i][j]进行递推,j代表的是余数,从0到9进行枚举,
由于每一位上都有数的限制,我们可以选择先把这一位上的0到9全部枚举,然后减去超过这个数的,或者先把之前一位的数先枚举到比它那个数小的范围,这一位从0到9枚举
,然后加上。
答案应该是d[r][0]-d[l-1][0],之前写错了。
#include <cstdio> #include <iostream> #include <cstring> #include<vector> #include<algorithm> #define LL long long #define maxn 10 #define MAXN 100000 #define inf 0x3f3f3f3f3f3f3f using namespace std; LL dp[20][20]; int c[20],d[20]; LL x,y; LL xx,yy; void init() { memset(dp,0,sizeof(dp)); } int getnum(LL num,int s[]) { int t=1; while(num>0) { s[t++]=num%10; num/=10; } for(int i=1;i<=(t-1)/2;i++) swap(s[i],s[t-i]); return t-1; } LL solve(LL len,int *s) { // printf("%d ",s[1]); //printf("%d ",s[2]); for(int i=0;i<=s[1];i++) dp[1][i]=1; int x=s[1]; for(int i=1;i<=len-1;i++) { for(int j=0;j<=9;j++) { for(int k=0;k<=9;k++) { /*if(i==1 && j==0) continue;*/ dp[i+1][(j+k)%10]+=dp[i][j]; } } for(int pp=s[i+1]+1;pp<=9;pp++) { int t=(x+pp)%10; dp[i+1][t]--; } x=(x+s[i+1])%10; } /* for(int i=1;i<=len;i++) { for(int j=0;j<=9 ;j++) { printf("%lld ",dp[i][j]); } printf(" "); }*/ //for(int i=2;i<=len;i++) // dp[i][0]+=dp[i-1][0]; // for(int i=1;i<=len;i++) // printf("%lld ",dp[i][0]);*/ return dp[len][0]; } int main() { int T; scanf("%d",&T); for(int i=1;i<=T;i++) { init(); scanf("%I64d%I64d",&x,&y); xx=getnum(x-1,c); yy=getnum(y,d); LL answer1,answer2; answer1=solve(xx,c); memset(dp,0,sizeof(dp)); answer2=solve(yy,d); /* for(int i=1;i<=xx;i++) printf("%d",c[i]); printf(" "); for(int i=1;i<=yy;i++) printf("%d",d[i]); printf(" ");*/ // printf("%lld ",answer2); // printf("%lld ",answer1); printf("Case #%d: %I64d ",i,answer2-answer1); } return 0; }