http://www.elijahqi.win/archives/599
1.函数(a.cpp/c/pas)
【问题描述】 给出两个正整数 L、R,设 f(x)=x 的各位数字之和,对于所有满足 L<=x<=R 的 正整数 x,求 f(x)的和。 【输入数据】 两个正整数 L、R。 【输出数据】 一个正整数表示答案。 【输入输出样例 1】 a.in a.out 912 15 【输入输出样例 1 说明】 答案=f(9)+f(10)+f(11)+f(12)=9+(1+0)+(1+1)+(1+2)=15 【输入输出样例 2】 a.in a.out 4216790354 1168268 【输入输出样例 3】 a.in a.out 233333333233429666 3272189 【输入输出样例 4】 a.in a.out 109370421979326187 35583321682 【数据规模和约定】 测试点编号 R 特殊性质 1 <=9 2 <=100 3 <=1000 4 <=100000 5 6
<=10^9 R-L<=1000007 8 9 10 对于 100%的数据:1<=L<=R<=10^9
这题考场上刚出来了,不过总分还是好低啊qwq
看到leoly给的数据范围,于是瞬间想到太大的部分我们预处理,再看下数据范围,10^5以上的部分应该已处理下pre[i] i其实后面省略了5个0,预处理出来。然后剩下的小于10^5的地方暴力做就好
#include<cstdio>
long long pre[110000];
int l,r;
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
scanf("%d%d",&l,&r);
if (r<=1e5||(r-l)<=100000){
long long ans=0;
for (int i=l;i<=r;++i){
int tmp=i;
while (tmp){
ans+=tmp%10;tmp/=10;
}
}
printf("%lld",ans);
} else{
//pre
pre[0]=2250000;int tmp1=1e5,tmp2=2;
pre[1]=pre[0];
for (int i=2;i<=1e5;++i){
int tmp=i-1;
pre[i]=pre[i-1]+pre[0];
while (tmp>0){
pre[i]+=(tmp%10)*1e5;tmp/=10;
}
}
for (int i=1;i<=1e5;++i){
int tmp=i;
while (tmp){
pre[i]+=tmp%10;tmp/=10;
}
}
//printf("%lld",pre[177]);
int ll=l/100000,rr=r/100000;
int tmp=ll;long long ans=0;
while (tmp>0){
ans+=(tmp%10)*(99999-(l%100000)+1);tmp/=10;
}
tmp=rr;
while (tmp>0){
ans+=(tmp%10)*(r%100000);tmp/=10;
}
ll+=1;
ans+=pre[rr]-pre[ll];
tmp=ll;
while (tmp){
ans+=tmp%10;tmp/=10;
}
ll=l%100000;
for (int i=ll;i<=99999;++i){
tmp=i;
while (tmp){
ans+=tmp%10;tmp/=10;
}
}
rr=r%100000;
for (int i=1;i<=rr;++i){
tmp=i;
while (tmp){
ans+=tmp%10;tmp/=10;
}
}
// if (l%100000==0) ans+=2250000;
printf("%lld",ans);
}
return 0;
}
一起看下官方题解吧
1.函数(a) 【80 分】 枚举 x 并计算 f(x),累加 f(x)得到答案。时间复杂度 O(R-L)。 【100 分】 计算十进制下每一位上每种数字出现的次数,进而算出答案。设 len 为 R 的位数, 时间复杂度 O(9*len)。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int L, R, l, a[20];
ll check(int L){
if(!L)return 0;
l=0; int x=L; while(x){a[++l]=x%10; x/=10;}
ll ans=0; int sum, x1, x2;
for(int i=1; i<=l; i++)
for(int j=1; j<=9; j++){
sum=x1=x2=0;
for(int k=l; k>=i+1; k--)x1=x1*10+a[k];
x2=1; for(int k=1; k<=i-1; k++)x2*=10;
if(j<a[i])sum=(x1+1)*x2;
if(j>a[i])sum=x1*x2;
if(j==a[i]){
sum=x1*x2;
x2=0; for(int k=i-1; k; k--)x2=x2*10+a[k]; x2++;
sum+=x2;
}
ans+=sum*j;
}
return ans;
}
int main(){
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
scanf("%d%d", &L, &R);
printf("%lld", check(R)-check(L-1));
return 0;
}