题目描述
小马克今年成为小学生。不久后她将进行她的第一次考试,其中包括数学考试。她非 常认真地复习,她认为自己已经准备好了。她的哥哥通过给她提出问题并解决的方式帮助 她。他的问题是给定一连串整数:依次由 1 个 1,2 个 2,3 个 3 等1223334444……。 现在他给马克两个整数 A 和 B;他的任务是求出由第 A 个到第 B 个数的。如果 A 是1,B 是 3,答案为 1+2+2=5。给一个问题,然后计算它们的和,马克的哥哥能够验证答案正确与否。
输入格式:(instruckcije.in)
只有一行,包括正整数 A 和B,1≤A≤B≤109。
输出格式:(instruckcije.out)
共一行,为和的值。
输入输出样例
输入样例#1:
1 3
输出样例#1:
5
输入样例#2:
3 7
输出样例#2:
15
数据范围:
对于30%的数据 1≤A≤B≤103;
对于60%的数据 1≤A≤B≤107;
对于100%的数据 1≤A≤B≤109;
分析问题
数字的出现是有规律:
- 数字 1 出现 1 次。
- 数字 2 出现 2 次。
- 数字 3 出现 3 次。
- 数字 4 出现 4 次。
- 以此类推。
我们可以模拟生成序列的规律,然后计算从第 A 个到第 B 个数字的和
建立模型
初始化当前数字
current_num = 1和剩余次数remaining = 1。遍历位置pos从 1 到 B:
如果
remaining == 0,说明当前数字已经输出完毕,移动到下一个数字(current_num++),并重置remaining = current_num。记录当前数字,并减少
remaining。计算从 A 到 B 的和
生成数字时,只累加位置在 A 到 B 之间的数字。
编写代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int A, B;
cin >> A >> B;
long long sum = 0;//用于统计区域数字和
int current_num = 1; // 当前数字
int remaining = 1; // 当前数字剩余的次数,从1开始
for (int pos = 1; pos <= B; pos++) {//从1开始,一直输出数字序列至B
//1 22 333 4444 55555
if (pos >= A) {//从起始位置A开始累加
sum += current_num;
}
remaining--; //当前数字数字n 不断减少 如3 会出现3次 3 2 1
if (remaining == 0) { //当前数字序列输出完
current_num++;//当前数字增加 1
remaining = current_num;//循环次数为当前次数
}
}
cout<<sum;
return 0;
}
代码解释
- 初始化:
current_num = 1:从数字 1 开始。remaining = 1:数字 1 需要出现 1 次。
- 遍历位置:
- 从位置 1 遍历到位置 B。
- 如果当前位置
pos在 A 和 B 之间,将current_num加到sum中。 - 减少
remaining,表示当前数字的剩余次数减 1。
- 更新数字:
- 当
remaining == 0时,说明当前数字已经输出完毕,移动到下一个数字(current_num++),并重置remaining = current_num。
- 输出结果:
- 遍历完成后,
sum中存储的就是从第 A 个到第 B 个数字的和。
示例验证
- 输入 1 3:
- 位置 1:数字 1,
sum = 1。 - 位置 2:数字 2,
sum = 1 + 2 = 3。 - 位置 3:数字 2,
sum = 3 + 2 = 5。 - 输出 5。
- 输入 3 7:
- 位置 3:数字 2,
sum = 2。 - 位置 4:数字 3,
sum = 2 + 3 = 5。 - 位置 5:数字 3,
sum = 5 + 3 = 8。 - 位置 6:数字 3,
sum = 8 + 3 = 11。 - 位置 7:数字 4,
sum = 11 + 4 = 15。 - 输出 15。