专栏文章
题解:UVA12517 Digit Sum
UVA12517题解参与者 5已保存评论 6
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @mioizxg1
- 此快照首次捕获于
- 2025/12/02 19:59 3 个月前
- 此快照最后确认于
- 2025/12/02 19:59 3 个月前
题解:UVA12517 Digit Sum
思路
我们可以计算 到 的数位和之和以及 到 的数位和之和,然后相减,最后再加上被减去的 的数位和。
就拿 这个数来讲吧,计算 到 的数位和之和,我们可以将它先拆解为 到 的数位和之和、 到 的数位和之和。
- 先算 到 的数位和之和:从百位来看,、 都被计算了 次, 被计算了 次;从十位来看,从 到 每 个数就会被计算 次,而 就被计算了 次;从个位来看,从 到 每 个数就会被计算 次,而 就也被计算了 次,由此得出,计算 到 的数位和之和的算式为:。
- 再算 到 的数位和之和:可以将它看成 到 的数位和之和加上少算的 次 。
所以得出:设 到 的数位和之和为 , 的长度设为 ,第一个数设为 ,除第一个数外后面的数为 ,就可以得出这样的式子:
当然啦,当 为 时 。
所以递归就写出来了:
CPPlong 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,可以去试试看的。还有一个注意的点,我们这里的函数算的数位和是包含 的,所以在之后的相减中要将 的数位和加回来(上文说过了)。
最后的最后,提供一下完整的代码吧。
CPP#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;
}
相关推荐
评论
共 6 条评论,欢迎与作者交流。
正在加载评论...