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.
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 ).
For test case
X
, output Case #X:
first, then output the number of good numbers in a single line.
2
1 10
1 20
Case #1: 0
Case #2: 1
The answer maybe very large, we recommend you to use long long instead of int.
题意:就是让你找到一个区间内的所有好数,这里好数的定义就是各位数字之和为10的倍数。
当时脑子有点不太好用了,没想到。仔细想想确实,每10个数中必定有且仅有一个好数,因为除了最后一位,你前面的各位数字之和模10之后必定是0~9的一个数字,所以再加上最后一位必定就是有且仅有一个好数惹,啊啊啊啊,竟然当时没想出来,啊啊啊啊。
最后再特殊判断一下最后一位能不能行就好惹,这里不理解自己再好好想想,譬如说46,10以内一个,11~20一个,21~30一个,31~40一个。最后40~46要看一看存不存在一个的。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,m;
const int MAXN=1e5+7;
int num[20];
long long get_num(long long x)
{
long long sum=x/10;
int cnt=0;
int p=0;
while(x)
{
num[cnt++]=x%10;
x/=10;
}
for(int i=cnt-1;i>0;--i)p+=num[i];
for(int i=0;i<=num[0];++i)
{
if((p+i)%10==0)sum++;
}
return sum;
}
int main()
{
int t;
scanf("%d",&t);
int ca=0;
long long l,r;
while(t--)
{
scanf("%lld %lld",&l,&r);
printf("Case #%d: %lld\n",++ca,get_num(r)-get_num(l-1));
}
return 0;
}
今天稍微学习了一下数位dp,学会了一点类似这种类型吧。
所以再附上一个dp解法:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,m;
const int MAXN=1e5+7;
int num[20];
long long dp[20][10];//位数为i,各位加起来模10之后为j
void get_f()
{
int i,j,k;
for(i=0;i<10;++i)dp[1][i]=1;
for(i=2;i<=18;++i)
{
for(j=0;j<10;++j)
{
for(k=0;k<10;++k)
{
dp[i][(j+k)%10]+=dp[i-1][j];
}
}
}
}
long long get_num(long long x)
{
if(x<0)return 0;
int i,j;
long long sum=0;
int cnt=0;
while(x)
{
num[++cnt]=x%10;
x/=10;
}
int p=0;
for(i=cnt;i>1;--i)//从高位开始进行枚举,缩小一下加上符合条件的。
{
for(j=0;j<num[i];++j)
{
sum+=dp[i-1][(10-(p+j)%10)%10];
}
p=(p+num[i])%10;
}
for(i=0;i<=num[1];++i)if((p+i)%10==0)sum++;//之后最终一位缩小因为要枚举到原数而且上面并不能计算,所以要在最后特判一下。
return sum;
}
int main()
{
int t;
scanf("%d",&t);
get_f();
int ca=0;
long long l,r;
while(t--)
{
scanf("%lld %lld",&l,&r);
printf("Case #%d: %lld\n",++ca,get_num(r)-get_num(l-1));
}
return 0;
}