题解:UVA12517 Digit Sum
HAPPINESS23333 · · 题解
题解:UVA12517 Digit Sum
题目传送门
思路
我们可以计算
就拿
- 先算
0 到300 的数位和之和:从百位来看,1 、2 都被计算了100 次,3 被计算了1 次;从十位来看,从1 到9 每100 个数就会被计算10 次,而300 就被计算了30 次;从个位来看,从1 到9 每10 个数就会被计算1 次,而300 就也被计算了30 次,由此得出,计算0 到300 的数位和之和的算式为:3 + ( 1 + 2 ) \times 100 + 30 \times [ ( 1 + 9 ) \times 9 \div 2 ] \times 2 = 3003 。 - 再算
300 到328 的数位和之和:可以将它看成0 到28 的数位和之和加上少算的28 次3 。
所以得出:设
当然啦,当
long long solve(long long n){
if(n<10){
return (1+n)*n/2;
}
long long final_out=0;
long long v=n;
long long len=0;
while(v>0){
len++;
final_out+=v%10;;
v/=10;
}
long long first=n/(long long)pow(10,len-1);
long long behind=n%(long long)pow(10,len-1);
return first*(behind+1)+solve(behind)+(first-1)*first/2*(long long)pow(10,len-1)+first*(len-1)*(long long)pow(10,len-2)*45;
}
没试过不开 long long,可以去试试看的。
还有一个注意的点,我们这里的函数算的数位和是包含
最后的最后,提供一下完整的代码吧。
#include<bits/stdc++.h>
using namespace std;
long long solve(int n){
if(n<10){
return (1+n)*n/2;
}
long long final_out=0;
long long v=n;
long long len=0;
while(v>0){
len++;
final_out+=v%10;;
v/=10;
}
long long first=n/(long long)pow(10,len-1);
long long behind=n%(long long)pow(10,len-1);
return first*(behind+1)+solve(behind)+(first-1)*first/2*(long long)pow(10,len-1)+first*(len-1)*(long long)pow(10,len-2)*45;
}
int main()
{
while(true){
long long N,M;
cin>>N>>M;
if(N==M && N==0){
break;
}
long long num=0;
num=solve(M)-solve(N);
while(N>0){
num+=N%10;
N/=10;
}
cout<<num<<endl;
}
return 0;
}