前言
节假日在家 闲来无事 ,那就 水 写一篇题解吧。
题目描述
前面一大堆废话,总结来说就是:
求 l -- R 区间的和
但是每一个数转换为 它本身所有数位的和,重复这个操作, 直到这个数 ⩽ 9
思路
我不知道各位神犇们是怎么做的,所以在此分享一下我的思路
前缀和(70pts)
这道题乍一眼看,不是前缀和吗!那么,可以写个函数:
int change(int x){
while(x >= 10){
int sum = 0;
while(x)
sum += x % 10, x /= 10;
x = sum;
}
return x;
}
接着用前缀和记录每一个数就可以了,
But, 但是这道题的数据范围:
1 ⩽ l ⩽ r ⩽ 260
数组直接爆炸,光荣RE
找规律(100pts)
从题目给的样例:
A9 = 9, A10 = 1, A11 = 2, A12 = 3 ... A18 = 9, A19 = 1...
不难看出:
这不就是小学学的周期问题吗?每十个数为一个周期。
那么我们就不需要将每一个数通过函数算一遍了,只要算出第一个数的函数值,
通过周期一直推到 R 就可以了
But, 但是这道题还是拿不了满分,于是我们可以再优化一下:
将两数之间的数字 除 9,可以直接求出有几个周期,并计算和
再加上它的余下的数就行。
最后
处理一下题目的一点细节,那么代码如下(不留坑了吧):
请在理解题目思路后,先自行编写
#include<bits/stdc++.h>
using namespace std;
long long a, b, n;
/*不开long long 会爆*/
long long change(long long x){
/*change函数,用于计算第一位*/
while(x >= 10){
long long sum = 0;
while(x) sum += x % 10, x /= 10;
x = sum;
}
return x;
}
int main(){
scanf("%lld", &n);
for(int i = 1; i <= n; i++){
scanf("%lld %lld", &a, &b);
long long t = change(a), ans = 0, xn;
for(int j = t; j <= 9 && a <= b; j++)
ans += j, a++;
/*方便计算周期*/
xn = b - a;
if(xn >= 0){
ans += xn / 9 * 45;
/*计算周期间的和*/
for(int j = 1; j <= xn % 9 + 1; j++){
ans += j;
}
/*加上剩下的数*/
}
printf("%lld\n", ans);
}
return 0;
}
那么,这道题就光荣AC了
咳, 点赞,懂?