求和(instruckcije)

题目描述

小马克今年成为小学生。不久后她将进行她的第一次考试,其中包括数学考试。她非 常认真地复习,她认为自己已经准备好了。她的哥哥通过给她提出问题并解决的方式帮助 她。他的问题是给定一连串整数:依次由 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;
}

代码解释

  1. 初始化
  • current_num = 1:从数字 1 开始。
  • remaining = 1:数字 1 需要出现 1 次。
  1. 遍历位置
  • 从位置 1 遍历到位置 B。
  • 如果当前位置 pos 在 A 和 B 之间,将 current_num 加到 sum 中。
  • 减少 remaining,表示当前数字的剩余次数减 1。
  1. 更新数字
  • remaining == 0 时,说明当前数字已经输出完毕,移动到下一个数字(current_num++),并重置 remaining = current_num
  1. 输出结果
  • 遍历完成后,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。

保存 编译 运行