您的位置:首页 > 编程语言 > Go语言

HDU 4722 Good Numbers(数位DP)

2016-11-07 11:25 417 查看
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4722

Good Numbers

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4395 Accepted Submission(s): 1427

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.

【中文题意】问你一个范围内有多少好数,好数的定义如下:他的所有位数之和能被10整除。

【思路分析】非常典型的数位DP,记录这些位数之和就行了。

【AC代码】

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define LL long long

LL dp[20][12],dight[20];

LL dfs(LL pos,LL pre,LL limit)
{
if(pos==-1)//终止条件
{
return !(pre%10);//终止时判断是否是10的倍数
}
if(!limit&&dp[pos][pre]!=-1)//如果之前计算过,现在就不需要计算了
{
return dp[pos][pre];
}
LL re=0;
LL tmp=limit?dight[pos]:9;
for(LL i=0;i<=tmp;i++)
{
re+=dfs(pos-1,(pre+i)%10,limit&&i==tmp);
}
if(!limit)
{
dp[pos][pre]=re;
}
return re;
}

LL cal(LL n)
{
LL len=0;
while(n)
{
dight[len++]=n%10;
n/=10;
}
return dfs(len-1,0,1);
}

int main()
{
memset(dp,-1,sizeof(dp));
int t,iCase=0;
scanf("%d",&t);
while(t--)
{
LL a,b;
scanf("%lld%lld",&a,&b);
printf("Case #%d: %lld\n",++iCase,cal(b)-cal(a-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU